From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 02:33:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 02:33:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.41556.74778 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTU-0004XB-5Y; Tue, 01 Dec 2020 02:33:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 41556.74778; Tue, 01 Dec 2020 02:33:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTU-0004X2-1o; Tue, 01 Dec 2020 02:33:04 +0000
Received: by outflank-mailman (input) for mailman id 41556;
 Tue, 01 Dec 2020 02:33:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTS-0004Wx-DG
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTS-0006aj-CS
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTS-00088H-BP
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5rO5lRoM8WZlJzrbm6cXiZuzUxT12qr4LzbYeQhZ8w8=; b=zImJRIc7I5vNx4o7nF/2ScLqD1
	L8cfrptYjccJlPyphAVBUtoJtshviQa6l/lTFsEZRNa8gBWMXqfUrYKghZN+/e5Dpoeuvq0IYnTWo
	meNns4FmWWHsTlHdtqSNVu4mOwXJiR7bojy8DrxS0apCWlRzCshXl8hi69g9MHN4GtNk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/events: modify struct evtchn layout
Message-Id: <E1kjvTS-00088H-BP@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 02:33:02 +0000

commit 43803dc0240f11a4b72c373f16e89508c23dcaa9
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Nov 30 14:04:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Nov 30 14:04:34 2020 +0100

    xen/events: modify struct evtchn layout
    
    In order to avoid latent races when updating an event channel put
    xen_consumer and pending fields in different bytes. This is no problem
    right now, but especially the pending indicator isn't used only when
    initializing an event channel (unlike xen_consumer), so any future
    addition to this byte would need to be done with a potential race kept
    in mind.
    
    At the same time move some other fields around to have less implicit
    paddings and to keep related fields more closely together.
    
    Finally switch struct evtchn to no longer use fixed sized types where
    not needed.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/event_fifo.c |  4 ++--
 xen/include/xen/sched.h | 34 ++++++++++++++++++----------------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 79090c04ca..f39e61105f 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -200,7 +200,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
      */
     if ( unlikely(!word) )
     {
-        evtchn->pending = 1;
+        evtchn->pending = true;
         return;
     }
 
@@ -535,7 +535,7 @@ static void setup_ports(struct domain *d, unsigned int prev_evtchns)
         evtchn = evtchn_from_port(d, port);
 
         if ( guest_test_bit(d, port, &shared_info(d, evtchn_pending)) )
-            evtchn->pending = 1;
+            evtchn->pending = true;
 
         evtchn_fifo_set_priority(d, evtchn, EVTCHN_FIFO_PRIORITY_DEFAULT);
     }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index a345cc01f8..4c380fd4b2 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -93,31 +93,33 @@ struct evtchn
 #define ECS_PIRQ         4 /* Channel is bound to a physical IRQ line.       */
 #define ECS_VIRQ         5 /* Channel is bound to a virtual IRQ line.        */
 #define ECS_IPI          6 /* Channel is bound to a virtual IPI line.        */
-    u8  state;             /* ECS_* */
-    u8  xen_consumer:XEN_CONSUMER_BITS; /* Consumer in Xen if nonzero */
-    u8  pending:1;
-    u16 notify_vcpu_id;    /* VCPU for local delivery notification */
-    u32 port;
+    unsigned char state;   /* ECS_* */
+#ifndef NDEBUG
+    unsigned char old_state; /* State when taking lock in write mode. */
+#endif
+    unsigned char xen_consumer:XEN_CONSUMER_BITS; /* Consumer in Xen if != 0 */
+    evtchn_port_t port;
     union {
         struct {
             domid_t remote_domid;
-        } unbound;     /* state == ECS_UNBOUND */
+        } unbound;          /* state == ECS_UNBOUND */
         struct {
             evtchn_port_t  remote_port;
             struct domain *remote_dom;
-        } interdomain; /* state == ECS_INTERDOMAIN */
+        } interdomain;      /* state == ECS_INTERDOMAIN */
         struct {
-            u32            irq;
+            unsigned int   irq;
             evtchn_port_t  next_port;
             evtchn_port_t  prev_port;
-        } pirq;        /* state == ECS_PIRQ */
-        u16 virq;      /* state == ECS_VIRQ */
+        } pirq;             /* state == ECS_PIRQ */
+        unsigned int virq;  /* state == ECS_VIRQ */
     } u;
-    u8 priority;
-#ifndef NDEBUG
-    u8 old_state;      /* State when taking lock in write mode. */
-#endif
-    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
+
+    bool pending;                  /* FIFO event channels only. */
+    unsigned char priority;        /* FIFO event channels only. */
+    unsigned short notify_vcpu_id; /* VCPU for local delivery notification */
+    uint32_t fifo_lastq;           /* Data for identifying last queue. */
+
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
@@ -133,7 +135,7 @@ struct evtchn
          * allocations, and on 64-bit platforms with only FLASK enabled,
          * reduces the size of struct evtchn.
          */
-        u32 flask_sid;
+        uint32_t flask_sid;
 #endif
     } ssid;
 #endif
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 02:33:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 02:33:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.41557.74782 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTe-0004Zj-71; Tue, 01 Dec 2020 02:33:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 41557.74782; Tue, 01 Dec 2020 02:33:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTe-0004Zb-3U; Tue, 01 Dec 2020 02:33:14 +0000
Received: by outflank-mailman (input) for mailman id 41557;
 Tue, 01 Dec 2020 02:33:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTc-0004ZS-HC
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTc-0006ap-GL
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTc-000892-Ez
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7qfSqKW3gUlvGqZ+hiAAhRVC68mf9lWcTV18+CoRBOo=; b=NytgIi36wThttp15lUlycnwiX3
	Jifq39tfRC6rPl0m5cT+TegJPtMJ+qgDKbBlOS/AWzY00dyzyXCNsHEVSwnH2ntNKFlHVDz8bQEt4
	Q9xON3SpBtG9tQqFm+f8cVunBjtSNtrqz3oM4k1GinVIHx7FGHSj65qIarzoRPHZBZ0c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/events: rework fifo queue locking
Message-Id: <E1kjvTc-000892-Ez@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 02:33:12 +0000

commit 71ac522909e9302350a88bc378be99affa87067c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Nov 30 14:05:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Nov 30 14:05:39 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index f39e61105f..a6cca4798d 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -87,38 +87,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -190,6 +158,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -204,17 +175,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -225,25 +246,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -262,8 +269,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -276,6 +283,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -284,15 +292,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 02:33:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 02:33:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.41558.74786 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTn-0004bp-AH; Tue, 01 Dec 2020 02:33:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 41558.74786; Tue, 01 Dec 2020 02:33:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kjvTn-0004bg-72; Tue, 01 Dec 2020 02:33:23 +0000
Received: by outflank-mailman (input) for mailman id 41558;
 Tue, 01 Dec 2020 02:33:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTm-0004bb-L8
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTm-0006b2-KM
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kjvTm-00089f-Iq
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 02:33:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PSQ6b7OQNJB8gZwNW6oNuK1wi2JPI27vYAyulvFPfcs=; b=w9p7J/rSJNkxtBpIXhI+eGuBUE
	C99UAGL0fYB8DIAyGqqlfFXFio3BUWuoXdoZcuexMPudRQSBHr9wagyf+vYnK7Z/NmbSsFf6+IIgA
	87OK0OsJjOkJVjbo/+SlHnT1sPAh5hQDeVHhqh1XNgCw/r3o9tgyzMfYSkoStm6CRlfc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
Message-Id: <E1kjvTm-00089f-Iq@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 02:33:22 +0000

commit 3ae469af8e680df31eecd0a2ac6a83b58ad7ce53
Author:     Roger Pau Monné <roge.rpau@citrix.com>
AuthorDate: Mon Nov 30 14:06:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Nov 30 14:06:38 2020 +0100

    x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
    
    The usage of idx instead of the GSI in vioapic_write_redirent when
    accessing gsi_assert_count can cause a PVH dom0 with multiple
    vIO-APICs to lose interrupts in case a pin of a IO-APIC different than
    the first one is unmasked with pending interrupts.
    
    Switch to use gsi instead to fix the issue.
    
    Fixes: 9f44b08f7d0e4 ('x86/vioapic: introduce support for multiple vIO APICS')
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Roger Pau Monné <roge.rpau@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/hvm/vioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 67d4a6237f..e64abee7a9 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -260,7 +260,7 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 0;
     else if ( !ent.fields.mask &&
               !ent.fields.remote_irr &&
-              hvm_irq->gsi_assert_count[idx] )
+              hvm_irq->gsi_assert_count[gsi] )
     {
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42123.75698 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6sy-0004p8-3Z; Tue, 01 Dec 2020 14:44:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42123.75698; Tue, 01 Dec 2020 14:44:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6sy-0004p0-0H; Tue, 01 Dec 2020 14:44:08 +0000
Received: by outflank-mailman (input) for mailman id 42123;
 Tue, 01 Dec 2020 14:44:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6sw-0004ov-C8
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6sw-0006AA-7R
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6sw-0007VE-6J
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9exqAl2LEgdtdA3mzxYrhbF6nbDy2H3KXdcAya6S0So=; b=H/X/l07tIfX5GDs0prjzvK4e4v
	DX1rzqNz/KJX+F1RuK9YoZ8/BbGeJOcNir9TA+20f0SoPY2zSd0gxAY315lI8ewwckP/Q//pHlL8X
	EFibSpdlJ2eAFD+xFkB1DWnmHRJ2x9bAOgVchPM53PD88lo1WPIAFpKmfxJm+KPyskIk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] xen/evtchn: rework per event channel lock
Message-Id: <E1kk6sw-0007VE-6J@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:06 +0000

commit 1ad177370df2db9129c97c7305962fc5ad298728
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:31:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:31:01 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 93c4fb9a79..8d1f9a9fc6 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2495,14 +2495,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("d%d:%3d(%c%c%c)%c",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-',
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 9aef7a860a..b4e83e0778 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -660,11 +660,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 97ba8e0795..f782ffeb82 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -85,7 +85,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -114,6 +114,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42124.75702 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6t8-0004pq-5C; Tue, 01 Dec 2020 14:44:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42124.75702; Tue, 01 Dec 2020 14:44:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6t8-0004pi-21; Tue, 01 Dec 2020 14:44:18 +0000
Received: by outflank-mailman (input) for mailman id 42124;
 Tue, 01 Dec 2020 14:44:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6t6-0004pc-Em
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6t6-0006Ae-DY
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6t6-0007Wp-Aa
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Dt6x+XczffL1O6izRIwxj4JJz8s22MPV9F7yjAuOkJA=; b=PsXIxWikZ5xMhSmI1mFoHHulNo
	1HRIt19sSnAmfrX7knen4tha/wyH52JdTw+X0Lx6MYx+d/3mf8WZ4r77N/nr0iZ7jHzddZuIs/MRU
	Q2GoXsfhx8niN5ZUADnv9wr2yyghtGoR9dRZIGWQ/mtCv0uY0MnekBNcul5uXYFk+wpQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kk6t6-0007Wp-Aa@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:16 +0000

commit d11d9775511e98157a53356c5cf1f37a1bdc9fe0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:32:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:32:18 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index b21c3783d3..a80bcf3e42 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 2dfa1f4295..87ea38b7a0 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 5513f399d5..a314bf85ce 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -281,16 +281,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 722919b762..c14bd07a2b 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -91,8 +91,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42125.75706 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tI-0004rA-7O; Tue, 01 Dec 2020 14:44:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42125.75706; Tue, 01 Dec 2020 14:44:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tI-0004r2-3h; Tue, 01 Dec 2020 14:44:28 +0000
Received: by outflank-mailman (input) for mailman id 42125;
 Tue, 01 Dec 2020 14:44:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tG-0004qp-JQ
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tG-0006Ak-I7
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tG-0007Y1-GO
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dVF2m5G4Nr+8sdTF/7kQdGjygJcYrU4aGq7qAVN9TvQ=; b=NsrslcmOBVq1mbt+41GcU/y6Nj
	gmtMzCpIsVoaaSBBhOnTUUxtO7Mt0Ac6wBJhRbasuHRNceaIPm3gk47+J7PCUYSnNbFGqRZHUJa8g
	3jPJsj6IwjeDJq2dhqCOFGFfgSxoxazY6eN5DGou9JWoNrnxL0cCPfQ6oMCkNEK1nVy8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86/vpt: fix build with old gcc
Message-Id: <E1kk6tG-0007Y1-GO@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:26 +0000

commit 7c6ee4ee232d2e7b2db1981aa7b9f578a2b0f0ad
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:32:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:32:51 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index d64467b631..ae7f715620 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -401,7 +401,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42126.75710 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tS-0004sv-AR; Tue, 01 Dec 2020 14:44:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42126.75710; Tue, 01 Dec 2020 14:44:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tS-0004sn-7I; Tue, 01 Dec 2020 14:44:38 +0000
Received: by outflank-mailman (input) for mailman id 42126;
 Tue, 01 Dec 2020 14:44:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tQ-0004se-PM
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tQ-0006Av-O8
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tQ-0007ZL-M3
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=TeiVy10bsVNOaWuHjTjAfHC+cRA66Rb3JC3YUw4SATI=; b=iqF6iiHqxn4Dix5fHBLYfFAFsY
	xXsU/vkA+S3Yj+MDJcAqd1ysflWGdfoBw0a5sh8emj13SOgYQg+k1DTdRwGmV6b7DzNNDNXKUDkq3
	m+O5MsUaXYsB7jbaMFk2eJGMA+mlcthqggzNkBo0t+Dj4TsVxZkTAuEOX5ttWyQt0ikI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kk6tQ-0007ZL-M3@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:36 +0000

commit 1cfb9b1c5b9e4c024f5f139d7a3d0357d2417b13
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:33:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:33:19 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index f782ffeb82..99e2f1aac5 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -117,8 +117,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42127.75714 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tc-0004ul-Bw; Tue, 01 Dec 2020 14:44:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42127.75714; Tue, 01 Dec 2020 14:44:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tc-0004ud-8s; Tue, 01 Dec 2020 14:44:48 +0000
Received: by outflank-mailman (input) for mailman id 42127;
 Tue, 01 Dec 2020 14:44:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ta-0004uT-Th
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ta-0006B4-Ss
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ta-0007aa-Rr
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=J1DvMbLaSwICrBXy1cLEEgyIDNQAWhDtfoVM5uAwVt8=; b=47jO4oFrIwnGUP+uaN3MR+HYWQ
	lgBnm3uqfGE+4Ve8vYq0SGu+ieUVCRZXkNPDYjSNE0y+WnXaIbZEJLL3Hh1TWjNLnSoBZhIGfBjkt
	XWgXQImS5R67K6PiEoiJJdsQ0CE11dxWOO7IAsLJgBj6DeZAwxZgOlEUjo31gEH6goTM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86/DMI: fix SMBIOS pointer range check
Message-Id: <E1kk6ta-0007aa-Rr@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:46 +0000

commit 8e6c236c3ef39d68bc3f0d170a1023c4c6914dce
Author:     Jan Beulich <JBeulich@suse.com>
AuthorDate: Tue Dec 1 15:33:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:33:57 2020 +0100

    x86/DMI: fix SMBIOS pointer range check
    
    Forever since its introduction this has been using an inverted relation
    operator.
    
    Fixes: 54057a28f22b ("x86: support SMBIOS v3")
    Signed-off-by: Jan Beulich <JBeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: 6befe598706218673b14710d90d00ce90763b372
    master date: 2020-11-24 11:25:29 +0100
---
 xen/arch/x86/dmi_scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index d24da1c53a..e5930d27ea 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -357,7 +357,7 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 			memcpy_fromio(&smbios3, q, sizeof(smbios3));
 			if (memcmp(smbios3.anchor, "_SM3_", 5) ||
 			    smbios3.length < sizeof(smbios3) ||
-			    q < p + 0x10000 - smbios3.length ||
+			    q > p + 0x10000 - smbios3.length ||
 			    !dmi_checksum(q, smbios3.length))
 				smbios3.length = 0;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:44:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:44:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42128.75718 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tl-0004vt-DM; Tue, 01 Dec 2020 14:44:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42128.75718; Tue, 01 Dec 2020 14:44:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tl-0004vl-AN; Tue, 01 Dec 2020 14:44:57 +0000
Received: by outflank-mailman (input) for mailman id 42128;
 Tue, 01 Dec 2020 14:44:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tl-0004ve-2A
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tl-0006BD-1M
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tk-0007bd-Vj
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:44:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=r5uF+6zmxFa+qmXN6j0mW/IDQ3T0k48hzIZy5LYZ0kg=; b=yp73veLyuMB9kvWM4Xy6iUcZg0
	N0YkSysNKvT8F0frInB9iK6HH6KB20vaLNDPMCTSsZ1oREFM4FSgJ14tju699ikybPMuJ/EbuPeRg
	oJuusa2MXxTGmBbEs9J40A6SwHJGX+i7z/1ucopGTc4UmntaN/eBNJEdyUUyDFSmjNiw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] xen/events: rework fifo queue locking
Message-Id: <E1kk6tk-0007bd-Vj@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:44:56 +0000

commit 72bd989f51878bc9ba61e930b0c29b921a30dc0d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:34:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:34:31 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42129.75722 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tw-0004xM-FQ; Tue, 01 Dec 2020 14:45:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42129.75722; Tue, 01 Dec 2020 14:45:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6tw-0004xA-Bz; Tue, 01 Dec 2020 14:45:08 +0000
Received: by outflank-mailman (input) for mailman id 42129;
 Tue, 01 Dec 2020 14:45:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tv-0004x0-5o
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tv-0006Bt-4y
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6tv-0007cf-42
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KLViHbFYQiODFqAseBPg9i7BU/3gv0npD2qPKcnvGSI=; b=b6MnvDoStUeblcIw6OPzrJ/v6I
	JzZJHVw966RK5pJJh3hukBV/irGSBZDgFAR5RYOXw1UXvoeeY37ZSrZaqx/Ls1cPoSEnGcLmNleuF
	wFcpq4uhnUgnv+ScXBA8F+x2WMXE3OEjEH+oWqIUw/ickvwqP32HE236UzoqdYvoqUdI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
Message-Id: <E1kk6tv-0007cf-42@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:07 +0000

commit 1d1d1f5391976456a79daac0dcfe7157da1e54f7
Author:     Roger Pau Monné <roge.rpau@citrix.com>
AuthorDate: Tue Dec 1 15:34:55 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:34:55 2020 +0100

    x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
    
    The usage of idx instead of the GSI in vioapic_write_redirent when
    accessing gsi_assert_count can cause a PVH dom0 with multiple
    vIO-APICs to lose interrupts in case a pin of a IO-APIC different than
    the first one is unmasked with pending interrupts.
    
    Switch to use gsi instead to fix the issue.
    
    Fixes: 9f44b08f7d0e4 ('x86/vioapic: introduce support for multiple vIO APICS')
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Roger Pau Monné <roge.rpau@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 3ae469af8e680df31eecd0a2ac6a83b58ad7ce53
    master date: 2020-11-30 14:06:38 +0100
---
 xen/arch/x86/hvm/vioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index b87facb0e0..52c5c636e3 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -260,7 +260,7 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 0;
     else if ( !ent.fields.mask &&
               !ent.fields.remote_irr &&
-              hvm_irq->gsi_assert_count[idx] )
+              hvm_irq->gsi_assert_count[gsi] )
     {
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42130.75726 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6u7-0004yV-Gd; Tue, 01 Dec 2020 14:45:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42130.75726; Tue, 01 Dec 2020 14:45:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6u7-0004yN-DY; Tue, 01 Dec 2020 14:45:19 +0000
Received: by outflank-mailman (input) for mailman id 42130;
 Tue, 01 Dec 2020 14:45:18 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6u6-0004yE-6n
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:18 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6u6-0006Cf-60
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:18 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6u6-0007fO-4K
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:18 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=M5kQOKqNSOQbL/XFbgPjmmuvDTMQcSA6DoOBdd6dfV8=; b=zXj0Pz0IGbII8LqnJi8GkfJOkO
	sr+B19HLmIvS+G6Myotrnhir1r2pqMHOBx/PEpG+3d/KC2My/FZHBrNgd6o9FDCYAz6kvvYN10O+/
	9lCLDEmCut3iSKrRApgx82UrKWgBH8GbNX1DIe50WfRV2NnXe6gQzrnFZZjMR2tScaNU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] update Xen version to 4.13.3-pre
Message-Id: <E1kk6u6-0007fO-4K@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:18 +0000

commit ec092152be2c0a834a575eaff71d70cc1de882e9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 13:54:02 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 13:54:02 2020 +0100

    update Xen version to 4.13.3-pre
---
 xen/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/Makefile b/xen/Makefile
index 4a7709bd5c..0fe43409a8 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 13
-export XEN_EXTRAVERSION ?= .2$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .3-pre$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:29 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:29 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42131.75730 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uH-0004zl-IO; Tue, 01 Dec 2020 14:45:29 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42131.75730; Tue, 01 Dec 2020 14:45:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uH-0004zc-F9; Tue, 01 Dec 2020 14:45:29 +0000
Received: by outflank-mailman (input) for mailman id 42131;
 Tue, 01 Dec 2020 14:45:28 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uG-0004zS-Ar
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:28 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uG-0006Cn-9x
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:28 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uG-0007gn-9C
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:28 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=40D01ufaVwgx0Mjc38b4Zwgfnq4Iy9cnl1J839BRmYw=; b=HpqckGgmlJyuvSW1RUXZGBqqTe
	Vf7bTZAkoZZXZiZSvX3c7NlonoPlLc03qpUUmqoC588BJgL30N7og7DJfmgO4cGc5w/YnDpRqMxF8
	I0Nu0p/82MK0fwDRP0pdaOLif8AkHuIH+Zj1iUH3jD1FlKT4CDehGpxMOvGCp87HIRnA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] xen/evtchn: rework per event channel lock
Message-Id: <E1kk6uG-0007gn-9C@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:28 +0000

commit 7d6f52d47b3d3ec9f0bec8b34e7f1a0e639849e8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:36:36 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:36:36 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index bb95583742..f05defbd7d 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2481,14 +2481,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("d%d:%3d(%c%c%c)%c",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-',
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index bbecbfa16f..36a7e30605 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -660,11 +660,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 8bb5bd7b38..89a9df5a63 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -83,7 +83,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -112,6 +112,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:39 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:39 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42132.75733 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uR-00051D-LY; Tue, 01 Dec 2020 14:45:39 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42132.75733; Tue, 01 Dec 2020 14:45:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uR-000516-Ii; Tue, 01 Dec 2020 14:45:39 +0000
Received: by outflank-mailman (input) for mailman id 42132;
 Tue, 01 Dec 2020 14:45:38 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uQ-00050y-Er
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:38 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uQ-0006D2-Dv
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:38 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uQ-0007iH-Cx
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:38 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QJ32EZ6bV+ovV7+Eq0a3zwoEVPBWWatALosu0DK5a/A=; b=DeN9tvvzey/TgacqSl0tFg9Fnt
	981KXgi+02oqTXM4uEgd+TvzAu/XYTuJbo+6A61k0vJf+t46HhUQFCQobjOiFCF7cIWJ0zBRzxqAw
	Mg7Q5prNliaNeNGjuKgakSAmEPpar4Wrnt2dIw0HqZ4s72NESPAkjr7evz5ZI3G/rHyk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kk6uQ-0007iH-Cx@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:38 +0000

commit 72031bcf69726efd05e34732b62a0f51ff2a257d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:37:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:37:39 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 2ba3ec95b4..e22d6160b5 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 2dfa1f4295..87ea38b7a0 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 794f465321..cf7f25cda2 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -280,16 +280,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 722919b762..c14bd07a2b 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -91,8 +91,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:49 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42133.75738 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6ub-000539-NG; Tue, 01 Dec 2020 14:45:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42133.75738; Tue, 01 Dec 2020 14:45:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6ub-000531-KO; Tue, 01 Dec 2020 14:45:49 +0000
Received: by outflank-mailman (input) for mailman id 42133;
 Tue, 01 Dec 2020 14:45:48 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ua-00052r-Ip
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:48 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ua-0006DD-Hw
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:48 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6ua-0007jV-Ge
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:48 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aQHedIKTwZnBaG7MOwbaIwO94XrV+eSvQUpWGHohTc0=; b=DyljIFdMWJeOsvIRFRaYL1Jpyg
	NRLhBBYDog/TZmTPEExG3Ol4hz3509F4o2QdvEexRVMQo4/cpAjXu5dO9oHXZGdXFIZJdbcdVwkbX
	ZNfjE70dLadwbFZFDWPLpyRVATWllMbxPhXEkMEQlqXUhdkvDenK5EP86njZEMj5WNuk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86/vpt: fix build with old gcc
Message-Id: <E1kk6ua-0007jV-Ge@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:48 +0000

commit 4f30743fdf815450bc9c052f2746751265a01aa4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:38:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:38:23 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 77b142406f..6d5f98767c 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -400,7 +400,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:45:59 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:45:59 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42134.75742 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6ul-00054U-P7; Tue, 01 Dec 2020 14:45:59 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42134.75742; Tue, 01 Dec 2020 14:45:59 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6ul-00054M-Ly; Tue, 01 Dec 2020 14:45:59 +0000
Received: by outflank-mailman (input) for mailman id 42134;
 Tue, 01 Dec 2020 14:45:58 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uk-00054E-MA
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:58 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uk-0006DM-LM
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:58 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uk-0007le-KS
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:45:58 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=f2nbM3fUZXVkZGVT8+PJuIrSpbWvBZ/+KqBjqjjAPvs=; b=LFOO90BW5MO38rfy/ScPXGPpLG
	e6jKR2iNO+mQPuXuIHS9O4lAW6juzPWpPNE+IMZDfJgon2bkjt+/QSZ8j1WrkmOe3FZ7LUX8AqMmh
	WKXeQS11paTPJzx4VPqX6HmU3hvbwYCC2sNzx9osTqvoaGYwhq8AOilCnfroN/KW9aio=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kk6uk-0007le-KS@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:45:58 +0000

commit d064b6581bbddf9ef4a8817a2f077dd2a0afa1da
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:39:02 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:39:02 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 89a9df5a63..8bf1b90261 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -115,8 +115,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:46:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:46:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42135.75747 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uv-00055m-RB; Tue, 01 Dec 2020 14:46:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42135.75747; Tue, 01 Dec 2020 14:46:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6uv-00055e-Ng; Tue, 01 Dec 2020 14:46:09 +0000
Received: by outflank-mailman (input) for mailman id 42135;
 Tue, 01 Dec 2020 14:46:08 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uu-00055W-QI
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:08 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uu-0006Di-PT
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:08 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6uu-0007nb-OK
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:08 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fyymAFeVrPx9nmDv6tr9m+h1qDaxtrHLfjw05myN0C4=; b=PNw1sRBFzCgmQCD8V5tP2lXa7Y
	il5Bv7VUNMTkvCYt7E63vf/3yD4lauhGwFo2tEVV7VHqR+J+zL7ePkPg7KmK1DQI0VkAurqUkHy0B
	KVpA8MSsk81nb+ZeDTwR4cDCpxWDjXsMxu3wbs/P25ayWyBl8rE5Y7x08hhKggOQNykU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86/DMI: fix SMBIOS pointer range check
Message-Id: <E1kk6uu-0007nb-OK@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:46:08 +0000

commit a1d8a6c24b87ff86072d071376587ac68211c6e7
Author:     Jan Beulich <JBeulich@suse.com>
AuthorDate: Tue Dec 1 15:39:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:39:48 2020 +0100

    x86/DMI: fix SMBIOS pointer range check
    
    Forever since its introduction this has been using an inverted relation
    operator.
    
    Fixes: 54057a28f22b ("x86: support SMBIOS v3")
    Signed-off-by: Jan Beulich <JBeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: 6befe598706218673b14710d90d00ce90763b372
    master date: 2020-11-24 11:25:29 +0100
---
 xen/arch/x86/dmi_scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index d24da1c53a..e5930d27ea 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -357,7 +357,7 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 			memcpy_fromio(&smbios3, q, sizeof(smbios3));
 			if (memcmp(smbios3.anchor, "_SM3_", 5) ||
 			    smbios3.length < sizeof(smbios3) ||
-			    q < p + 0x10000 - smbios3.length ||
+			    q > p + 0x10000 - smbios3.length ||
 			    !dmi_checksum(q, smbios3.length))
 				smbios3.length = 0;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:46:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:46:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42136.75750 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6v5-000579-SJ; Tue, 01 Dec 2020 14:46:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42136.75750; Tue, 01 Dec 2020 14:46:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6v5-000571-PE; Tue, 01 Dec 2020 14:46:19 +0000
Received: by outflank-mailman (input) for mailman id 42136;
 Tue, 01 Dec 2020 14:46:19 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6v4-00056r-V3
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:18 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6v4-0006EI-TJ
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:18 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6v4-0007pG-Sa
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:18 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jGzwP8Nh3dn76ZoP4PK9NnpsBdts7F5fMbOEUkG1BCE=; b=TJsd11G99W1pBafarWFB6mMO9J
	4eobIJxN1ulXU60PvEkCgyNVvDviLcPABlM4dT60iAzO2A38ssJLhBeA7/w65X/xuKNAu7uLMbINw
	o4M//2Xl0TZ3Ldg9bddlxdxfnuSvnljXQwRHpEiEI2EKZGk2JkArBLT1+4jtunc1x0wM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] xen/events: rework fifo queue locking
Message-Id: <E1kk6v4-0007pG-Sa@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:46:18 +0000

commit 74c5729bb33d25eb2c6a5ea1fd9936d9798bb74c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:40:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:40:24 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:46:30 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:46:30 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42137.75754 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6vF-00058g-Vf; Tue, 01 Dec 2020 14:46:29 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42137.75754; Tue, 01 Dec 2020 14:46:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk6vF-00058W-SS; Tue, 01 Dec 2020 14:46:29 +0000
Received: by outflank-mailman (input) for mailman id 42137;
 Tue, 01 Dec 2020 14:46:29 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6vF-00058O-1l
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:29 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6vF-0006EQ-12
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:29 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk6vF-0007r0-02
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:46:29 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fIDFJAmEXa6ustJZ+b0MVRBMdz9X5BndguukQH1qDtE=; b=1UiPPb6fw+E1SemGvqhP2HEYFP
	GtD5A1hw8F2goy5HWp4MK41yyTAT2zmWYGNi2Z3eRfHgbjHpdN/NxECueWvCpj3Xzb9zQtYpDjZij
	Zs1n07tqQVeXwVUTY/daGOTj71+euOCXDmSmrSjeMHMkx4U2re234ioFePRSRUl9fTuE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
Message-Id: <E1kk6vF-0007r0-02@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:46:29 +0000

commit b5302273e2c51940172400486644636f2f4fc64a
Author:     Roger Pau Monné <roge.rpau@citrix.com>
AuthorDate: Tue Dec 1 15:41:07 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:41:07 2020 +0100

    x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
    
    The usage of idx instead of the GSI in vioapic_write_redirent when
    accessing gsi_assert_count can cause a PVH dom0 with multiple
    vIO-APICs to lose interrupts in case a pin of a IO-APIC different than
    the first one is unmasked with pending interrupts.
    
    Switch to use gsi instead to fix the issue.
    
    Fixes: 9f44b08f7d0e4 ('x86/vioapic: introduce support for multiple vIO APICS')
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Roger Pau Monné <roge.rpau@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 3ae469af8e680df31eecd0a2ac6a83b58ad7ce53
    master date: 2020-11-30 14:06:38 +0100
---
 xen/arch/x86/hvm/vioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 9aeef32a14..d899dd9707 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -260,7 +260,7 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 0;
     else if ( !ent.fields.mask &&
               !ent.fields.remote_irr &&
-              hvm_irq->gsi_assert_count[idx] )
+              hvm_irq->gsi_assert_count[gsi] )
     {
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:55:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:55:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42146.75769 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73a-00069u-SW; Tue, 01 Dec 2020 14:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42146.75769; Tue, 01 Dec 2020 14:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73a-00069m-Pd; Tue, 01 Dec 2020 14:55:06 +0000
Received: by outflank-mailman (input) for mailman id 42146;
 Tue, 01 Dec 2020 14:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73Z-00069h-QE
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73Z-0006PC-La
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73Z-0000Da-It
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PDZpKS5aDDGYfi8N+SG78zCEA7Zdh6nh4Q+WzXuuRSk=; b=5hvdmSlcMdYWL890IOOHxeEWql
	ssv8B0DqwdOLeaAirkOZJ6bJncsU2GCIOp+5E0nVIHw8FrBdXAI4JNoWD/rVegpvzr0SVwbQBkU9D
	XkDlij2yULuI7N433RjQrfSwfD89DJ7IAi/Y9FEdIDmoWFe+6TWAMF1yYoxqtSQ0s2sk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] xen/evtchn: rework per event channel lock
Message-Id: <E1kk73Z-0000Da-It@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:55:05 +0000

commit 5c15a1cccb8d336eb46a6ca7bda4d9df2d6327a1
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:45:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:45:03 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index f49ce8cf57..29af31a1db 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2371,14 +2371,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 91d44d6f1c..f671ec0d89 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -662,11 +662,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index b918624327..eb8f63da69 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -83,7 +83,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -112,6 +112,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:55:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:55:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42147.75774 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73k-0006Aj-UK; Tue, 01 Dec 2020 14:55:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42147.75774; Tue, 01 Dec 2020 14:55:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73k-0006Ab-RH; Tue, 01 Dec 2020 14:55:16 +0000
Received: by outflank-mailman (input) for mailman id 42147;
 Tue, 01 Dec 2020 14:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73j-0006AV-T6
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73j-0006Pw-Ru
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73j-0000F4-PH
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=mGTC8wbqFx5HS4EEAVDFb2LUBeIAH3Erw3128FEoepU=; b=EMkNKjK1higSXKa+OMmj5gVlI/
	hj4bxjjl5xi37xunuh2RXlKrbUMGecC6ZmgCW399Eh3qckvkdsmLsbyP7jxnA2DCtf9kHB6pSv7pv
	kI//AyUo2t4btbOnVbeMP9jPckDtraWLcBl3KHPHonHs2f2ouSsSwl/YKdz1RCgJhiso=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kk73j-0000F4-PH@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:55:15 +0000

commit 1dd870ec2b6080d67944fd02d2d548716d7551bb
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:46:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:46:00 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 56cfbbe2d8..fc9d6b5bf0 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 7c170f520a..640c708659 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 277fb66e91..3d00c747f6 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -280,16 +280,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 32ecc0ea2a..93386bd7a1 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:55:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:55:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42148.75778 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73w-0006CJ-1H; Tue, 01 Dec 2020 14:55:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42148.75778; Tue, 01 Dec 2020 14:55:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk73v-0006CB-UK; Tue, 01 Dec 2020 14:55:27 +0000
Received: by outflank-mailman (input) for mailman id 42148;
 Tue, 01 Dec 2020 14:55:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73u-0006Bw-1T
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73u-0006Q6-0W
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk73t-0000Gx-Ut
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JYpSIu8mSZgBAgFcW4+vC2zKdJdIXY+VrkJmOceNzv8=; b=qhjgPW0JrOO/8sVgA6ZkvyTh0Q
	VNVDGv/Vfi8Q7FIDHF1pWAU3y3dSDOBVfVm1HgnSt4rQJBDoyCSyA+cmAduyqkXYKeCJWsO64hdk2
	qi4ztI4VZ8bP3qFWhtN/JjB/k6j9J1I+NpCZKWIQlUVJ9mSdgpSTw5s4GUwLCSLp/Fx0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kk73t-0000Gx-Ut@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:55:25 +0000

commit 40ab01947f10f0ac8cbbb629b83241106bed23e4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:46:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:46:34 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index eb8f63da69..db645102e2 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -115,8 +115,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:55:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:55:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42149.75782 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk746-0006Dg-2y; Tue, 01 Dec 2020 14:55:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42149.75782; Tue, 01 Dec 2020 14:55:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk746-0006DY-02; Tue, 01 Dec 2020 14:55:38 +0000
Received: by outflank-mailman (input) for mailman id 42149;
 Tue, 01 Dec 2020 14:55:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk744-0006DI-55
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk744-0006QI-4C
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk744-0000II-3G
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1cL6TOPby8uF+zUaEEUwUHxlc05Sq1XhvrX5ZQ/gpvY=; b=liAeui47yw+duWkNYaB4vRjpVv
	+ahYcHPS1BVnjG0K8ztiau9rFq//ubH1Rdr+Cmriq7jYQO2kCZjZKgCfCDKzlnGk+iuZB/RQFu41b
	vbUkskcxTYKjau1VJOSNKfSteMUNjo9/DoS+MFooBlD2EZaBMFAzcjTd3eiR7L+60kVs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] xen/events: rework fifo queue locking
Message-Id: <E1kk744-0000II-3G@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:55:36 +0000

commit 14f577b2dd99944692cba570e6096d08ef00a2c4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:47:26 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:47:26 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 14:55:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 14:55:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42150.75786 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk74G-0006Ff-4a; Tue, 01 Dec 2020 14:55:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42150.75786; Tue, 01 Dec 2020 14:55:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk74G-0006FX-1b; Tue, 01 Dec 2020 14:55:48 +0000
Received: by outflank-mailman (input) for mailman id 42150;
 Tue, 01 Dec 2020 14:55:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk74E-0006FN-8Q
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk74E-0006QQ-7S
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk74E-0000JH-6d
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 14:55:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=chEz4/8aGih6aRQUNuZB6f1EqhF9Zrua7n+OEnDv6yI=; b=tPAGYVWcZ45UnQK78YQNqajrez
	8wN5Y5UnwprmPbA+2hZuuCYN9DUuCWu442P6YXzeVfSRyfgBIE3rHN1YwvCtHcTc/UKLyV6O6A1Vo
	ddkXScuWcblBYtoP9/pt27y6FfhpHYggy265PT5x/p1itU/QzASWRcKdi6lxA5wRCv08=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] x86/vpt: fix build with old gcc
Message-Id: <E1kk74E-0000JH-6d@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 14:55:46 +0000

commit 8145d38b48009255a32ab87a02e481cd09c811f9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:48:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:48:08 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 77b142406f..6d5f98767c 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -400,7 +400,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:11:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:11:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42208.75886 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8F9-0006UH-1e; Tue, 01 Dec 2020 16:11:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42208.75886; Tue, 01 Dec 2020 16:11:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8F8-0006U9-Uv; Tue, 01 Dec 2020 16:11:06 +0000
Received: by outflank-mailman (input) for mailman id 42208;
 Tue, 01 Dec 2020 16:11:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8F7-0006U4-Lg
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8F7-0008Ve-Js
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8F7-0007q0-Hu
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=IfAa40wRWS09PyxjR4/tsz1i18bcp+HO/aHD8H2zQkg=; b=iSw5UUIc4vfBFN3wTU/1YomCwq
	/gkfd85EsvPzLam4Nrz/xZBSfMjfyyH01cGtpJfUIUJQwYGyULAgGabp0iqjEYUVGxb6HIkLhn4IB
	A1oMlwbeVXBgce8v7eyKs0kSqq0IIqn1RnxnW2DiGKYIgOPEKfCQzvxGm0DSQ+0+FiMc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] evtchn/fifo: use stable fields when recording "last queue" information
Message-Id: <E1kk8F7-0007q0-Hu@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:11:05 +0000

commit 2a730d5b6ad1ea95c3d67fa12ab0091d32b29505
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 17:03:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:03:12 2020 +0100

    evtchn/fifo: use stable fields when recording "last queue" information
    
    Both evtchn->priority and evtchn->notify_vcpu_id could change behind the
    back of evtchn_fifo_set_pending(), as for it - in the case of
    interdomain channels - only the remote side's per-channel lock is held.
    Neither the queue's priority nor the vCPU's vcpu_id fields have similar
    properties, so they seem better suited for the purpose. In particular
    they reflect the respective evtchn fields' values at the time they were
    used to determine queue and vCPU.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    master commit: 6f6f07b64cbe90e54f8e62b4d6f2404cf5306536
    master date: 2020-10-02 08:37:35 +0200
---
 xen/common/event_fifo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 45c024739d..98742ba9cb 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -224,8 +224,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = evtchn->notify_vcpu_id;
-            evtchn->last_priority = evtchn->priority;
+            evtchn->last_vcpu_id = v->vcpu_id;
+            evtchn->last_priority = q->priority;
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:11:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:11:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42209.75890 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8FJ-0006V2-3n; Tue, 01 Dec 2020 16:11:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42209.75890; Tue, 01 Dec 2020 16:11:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8FJ-0006Uu-0L; Tue, 01 Dec 2020 16:11:17 +0000
Received: by outflank-mailman (input) for mailman id 42209;
 Tue, 01 Dec 2020 16:11:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FH-0006Up-QG
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FH-0008WQ-OA
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FH-0007r2-Mm
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nDnsQEWlYG21bZLd9NtVyT/0TmZty63g7CXs9EosAz4=; b=ShnsiheV57FpP5/OAneVx9+4I1
	lzZTVkj7etSRdi3eXKTYyDmJskmSWG9PwAi9TME5WoVWTmFZkuBpzI6LjmeA/MOfPAjXqySdzE7ej
	T/mQoECFWUzj+csbXeRoiksRzrqM8AjhuRSU1kfU3ozIuBQRhEXSLCSpzmc7X7BB+b0s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] xen/evtchn: rework per event channel lock
Message-Id: <E1kk8FH-0007r2-Mm@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:11:15 +0000

commit 4438fc14a6c60b265a47c780d6a61d4f3015a297
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:04:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:04:43 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 9878486073..a293270cf2 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2331,14 +2331,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 4b7d498c00..f8883bd102 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -616,11 +616,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 0066c8a87f..7f2ad9d826 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -429,14 +454,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -453,7 +478,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
          (d->vcpu[vcpu] == NULL) )
@@ -466,13 +490,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -516,7 +540,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -549,14 +572,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -577,7 +600,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -677,14 +699,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -692,9 +714,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -714,7 +736,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -727,7 +748,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -762,7 +783,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -789,9 +810,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -820,9 +843,11 @@ static void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -832,7 +857,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -847,9 +871,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1044,15 +1070,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1298,7 +1326,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1311,14 +1338,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1350,7 +1377,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1365,7 +1391,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1375,7 +1402,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 87a4aade86..b0c39d402c 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -103,6 +103,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -236,11 +251,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -255,11 +269,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 7e4ad5d51b..3c1284c3da 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -82,7 +82,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -111,6 +111,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:11:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:11:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42210.75893 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8FT-0006We-6S; Tue, 01 Dec 2020 16:11:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42210.75893; Tue, 01 Dec 2020 16:11:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8FT-0006WU-3T; Tue, 01 Dec 2020 16:11:27 +0000
Received: by outflank-mailman (input) for mailman id 42210;
 Tue, 01 Dec 2020 16:11:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FS-0006WJ-0I
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FR-00004r-Up
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8FR-0007s7-R1
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GSIS/585w8FxFFxrAq/xM8JvQoyZC5RO1zWbWNimbWc=; b=c9MDytBRxFclQZK4GpIw+pHAAB
	uTz3xGn0Et0YLs6jMqqDPg3nmbWzW8g1qIJA0b9sjAnHDmb+A1QtSUvERIBZYPtpSZbdRexQqGT5O
	HDWmBhYqNBOwuaMXhyHdZNMDIlI4kfwtj/URu1DcQI4DUXpxwFrHUwQtP0QFbP5rpZts=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kk8FR-0007s7-R1@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:11:25 +0000

commit 4fe13265f99fb450085c07037a6096fa5e44351b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:05:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:05:27 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 7f2ad9d826..26198184b1 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -740,12 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index a670880106..2779819e1e 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 8917329225..a3e6108a34 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 17aa543fca..78bc32602e 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -278,16 +278,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 8426b36c72..bfc69f4acd 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:11:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:11:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42211.75898 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8Fd-0006YG-7z; Tue, 01 Dec 2020 16:11:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42211.75898; Tue, 01 Dec 2020 16:11:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8Fd-0006Y8-4z; Tue, 01 Dec 2020 16:11:37 +0000
Received: by outflank-mailman (input) for mailman id 42211;
 Tue, 01 Dec 2020 16:11:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fc-0006Xy-2n
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fc-00006P-1u
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fc-0007sz-1C
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=83SAh4/BCDVaHDnN/7zUWgTBPeallzj3PfIJvNCaTUI=; b=3U6jcrR3mA+H7X3CLfh27AqbWc
	9xPMzdTAgBxUnPoPmYMhqvJDpyX1Nx65TmfmpSzTTtvjRWLR/BvG3SO0tjvLM5dry1ZtiNtCgvhFt
	mmHpzd3tM0IdDJfnbljnikFRS7XpWWgGjsl+txiB0ktrEBzKuMdAFLXtYZD/tOwgU7CQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kk8Fc-0007sz-1C@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:11:36 +0000

commit 8ab4af91fab6618994e5857b65aec5896915d9c5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:06:15 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:06:15 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 98742ba9cb..b1951a29ad 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -64,16 +72,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -224,8 +234,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 3c1284c3da..81af1209dd 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -114,8 +114,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:11:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:11:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42212.75902 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8Fn-0006aF-9k; Tue, 01 Dec 2020 16:11:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42212.75902; Tue, 01 Dec 2020 16:11:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8Fn-0006a7-6c; Tue, 01 Dec 2020 16:11:47 +0000
Received: by outflank-mailman (input) for mailman id 42212;
 Tue, 01 Dec 2020 16:11:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fm-0006Zz-7K
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fm-00006k-5Q
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8Fm-0007u6-4V
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:11:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dmCTu3TbnN+fDcXEUNei343eONGEckC7kCUdV3gaQnk=; b=wlErbdSf9JylVqPujBpzdY/I33
	M4KQlSMAr690371NSvuaQEOUY7EndqPQ/Kl79KJMf5ShVBr68JXWGpLWSP/Klx5//3RTJ105o4XYk
	oO1JF+QFmLGhu7Zs7OYVV2j7C94fXz3jo6ynAJPWBUNLxovHIO4VPeFJk5zt/pFtA32A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] xen/events: rework fifo queue locking
Message-Id: <E1kk8Fm-0007u6-4V@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:11:46 +0000

commit 41a822c3926350f26917d747c8dfed1c44a2cf42
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:07:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:07:03 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index b1951a29ad..0a90a8404d 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -65,38 +65,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -168,6 +136,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -182,17 +153,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -203,25 +224,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -240,8 +247,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -254,6 +261,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -262,15 +270,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:44:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:44:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42219.75908 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8l4-0000xK-Ge; Tue, 01 Dec 2020 16:44:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42219.75908; Tue, 01 Dec 2020 16:44:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8l4-0000xC-Dl; Tue, 01 Dec 2020 16:44:06 +0000
Received: by outflank-mailman (input) for mailman id 42219;
 Tue, 01 Dec 2020 16:44:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8l3-0000x7-Oq
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8l3-0000li-LW
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8l3-0002vs-Ij
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=14hFjAAubfnzdR5Wj4E3+LhSDxkxJiK8gRmEqPh/s6s=; b=y+VX8wjNZIul4+rhIL4cXLCb2b
	lRF4FweH38xwMrsJ06oYcD3iQ9RGGWaQAdycMB4oy1Ck1gcLlKdJFIAqkH4ekmNihNmeZL9UL2sW5
	DPSuHBdws2SBybzHeIS+xk8ddjntOrvqIMsaIIJR/Lcr1FKzcVZWUAaoLqb9AyT06ZRs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] evtchn/fifo: use stable fields when recording "last queue" information
Message-Id: <E1kk8l3-0002vs-Ij@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:44:05 +0000

commit 1fdcfdbfb2b1920a0bbaf8281cb8a7f6e37b2a6f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 17:34:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:34:38 2020 +0100

    evtchn/fifo: use stable fields when recording "last queue" information
    
    Both evtchn->priority and evtchn->notify_vcpu_id could change behind the
    back of evtchn_fifo_set_pending(), as for it - in the case of
    interdomain channels - only the remote side's per-channel lock is held.
    Neither the queue's priority nor the vCPU's vcpu_id fields have similar
    properties, so they seem better suited for the purpose. In particular
    they reflect the respective evtchn fields' values at the time they were
    used to determine queue and vCPU.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    master commit: 6f6f07b64cbe90e54f8e62b4d6f2404cf5306536
    master date: 2020-10-02 08:37:35 +0200
---
 xen/common/event_fifo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 45c024739d..98742ba9cb 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -224,8 +224,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = evtchn->notify_vcpu_id;
-            evtchn->last_priority = evtchn->priority;
+            evtchn->last_vcpu_id = v->vcpu_id;
+            evtchn->last_priority = q->priority;
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:44:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:44:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42220.75913 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lE-0000y5-IS; Tue, 01 Dec 2020 16:44:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42220.75913; Tue, 01 Dec 2020 16:44:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lE-0000xx-FK; Tue, 01 Dec 2020 16:44:16 +0000
Received: by outflank-mailman (input) for mailman id 42220;
 Tue, 01 Dec 2020 16:44:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lD-0000xq-R9
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lD-0000mC-QD
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lD-0002y6-Ok
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Y2jpS8Q9FpreS8WuQdpC1bpjAaL3Kb1oySsBaZ4m5P8=; b=5NA4QQzxnajllwPvFNsdmdSAWx
	XXjg3CfGupZB/YEYcRDdkJzcCA//BOeIlmg+WeJHCgM2PUudxpRrB6tdp9idGDkw+uQUoR93q0O7T
	8nGUBq+Cnbw1AeedsD4KfdCK6+SF+Am+IoVuFq7QoxpFu9fnmu52CUxsh3CP1npSoydc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] xen/evtchn: rework per event channel lock
Message-Id: <E1kk8lD-0002y6-Ok@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:44:15 +0000

commit f91d2a96b56039c4a6e63b605ac561d68847f515
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:35:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:35:30 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 01a678b5e2..7b2367e728 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2330,14 +2330,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 973b2c31e4..8f01128521 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -603,11 +603,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 84d58454d2..c20118f104 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -138,7 +172,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -256,7 +290,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -272,14 +305,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -292,32 +325,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -327,7 +354,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -363,7 +389,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -380,7 +406,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -403,7 +429,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -436,14 +461,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -460,7 +485,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
          (d->vcpu[vcpu] == NULL) )
@@ -473,13 +497,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -523,7 +547,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -556,14 +579,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -584,7 +607,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -684,14 +706,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -699,9 +721,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -721,7 +743,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -734,7 +755,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -769,7 +790,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -796,9 +817,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -827,9 +850,11 @@ static void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -839,7 +864,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -854,9 +878,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1052,15 +1078,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1306,7 +1334,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1319,14 +1346,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1358,7 +1385,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1373,7 +1399,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1383,7 +1410,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 87a4aade86..b0c39d402c 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -103,6 +103,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -236,11 +251,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -255,11 +269,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 831927fbc4..800b50289d 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -81,7 +81,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -110,6 +110,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:44:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:44:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42221.75917 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lO-0000za-Lm; Tue, 01 Dec 2020 16:44:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42221.75917; Tue, 01 Dec 2020 16:44:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lO-0000zS-Id; Tue, 01 Dec 2020 16:44:26 +0000
Received: by outflank-mailman (input) for mailman id 42221;
 Tue, 01 Dec 2020 16:44:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lO-0000zL-1v
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lN-0000mP-Uc
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lN-0002zM-T9
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Ryyk6q8hSs22ak/0Wm67+t6VDzAGDlDIUP22SZai7Tk=; b=uMhIj/+1NAej8GUYSocQcIMoI7
	G3uOCmd50UBE5OrK0HemZ8W6+CrEC3SSlvvQNdKWkAox0+UPHzNIlzwb3pl2uoJtpXM8hsAhaJcjt
	6s6TIkubRm6rgkZBcGt/YD0OoS7wdtcmtxS4dx4q9H0oj8U2/HDxJxv/Obd3ZHNW4z8k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kk8lN-0002zM-T9@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:44:25 +0000

commit f79f47f21c45771ee608b30d2fa5429efb7919e0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:36:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:36:09 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index c20118f104..3a61a04495 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -747,12 +747,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index d0b4b097c0..2a299f7569 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 8917329225..a3e6108a34 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 211cfb9a4b..f01b4cfaaa 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -278,16 +278,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 8426b36c72..bfc69f4acd 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:44:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:44:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42222.75920 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lY-00011E-Mw; Tue, 01 Dec 2020 16:44:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42222.75920; Tue, 01 Dec 2020 16:44:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lY-000117-K9; Tue, 01 Dec 2020 16:44:36 +0000
Received: by outflank-mailman (input) for mailman id 42222;
 Tue, 01 Dec 2020 16:44:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lY-000110-35
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lY-0000mb-1p
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8lY-00030R-0s
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JTC6xxvzpRM1N0mZecvE/z9MoM80ntKIw85yaUAZQkc=; b=MMIGH5YUjOat4FLzGtW/nRBYaD
	/2t/n8E9on+fofe4vAgTR9AxW6lGbwnNZhFyZqiriboptT+zS2itMzDj5ctod8h9YNiuuh5rXiEzY
	m82CJUpsi+PfDETllbk9wIh12KhskStk3y9kNqvrIoiENjcQSSegoG2TSM9DbFzB7rsc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kk8lY-00030R-0s@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:44:36 +0000

commit 8eb5328e2ec6aa15e371ab64348265b26f00cdf5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:36:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:36:41 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 98742ba9cb..b1951a29ad 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -64,16 +72,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -224,8 +234,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 800b50289d..88740cd2ca 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -113,8 +113,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 01 16:44:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 01 Dec 2020 16:44:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42223.75925 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lj-000131-PI; Tue, 01 Dec 2020 16:44:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42223.75925; Tue, 01 Dec 2020 16:44:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kk8lj-00012r-M8; Tue, 01 Dec 2020 16:44:47 +0000
Received: by outflank-mailman (input) for mailman id 42223;
 Tue, 01 Dec 2020 16:44:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8li-00012h-69
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8li-0000mn-5E
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kk8li-00031Z-4K
 for xen-changelog@lists.xenproject.org; Tue, 01 Dec 2020 16:44:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=RUGKdP3o/ytIwYp9p315ukiQV2JiXknhQ6O+BliE2FE=; b=iOFAF1dBSD0+bkSMaTBnEjpG97
	oXBU+iKNXSjdTENX3tMpbF273HsIgTYNfdVmDbzksRURtum4ePw428Q0pjOlHSeUdorUC/drgrSKV
	tYGi1veEjpc2pX3pQOkyfw8iPCC9SUkBbZZz3qSxXR35zovYAdnPO31GkwXkFVkrET0w=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] xen/events: rework fifo queue locking
Message-Id: <E1kk8li-00031Z-4K@xenbits.xenproject.org>
Date: Tue, 01 Dec 2020 16:44:46 +0000

commit 1d72d9915edff0dd41f601bbb0b1f83c02ff1689
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:37:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:37:21 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index b1951a29ad..0a90a8404d 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -65,38 +65,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -168,6 +136,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -182,17 +153,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -203,25 +224,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -240,8 +247,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -254,6 +261,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -262,15 +270,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42386.76193 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQB-00061J-NI; Wed, 02 Dec 2020 00:55:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42386.76193; Wed, 02 Dec 2020 00:55:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQB-00061B-Jd; Wed, 02 Dec 2020 00:55:03 +0000
Received: by outflank-mailman (input) for mailman id 42386;
 Wed, 02 Dec 2020 00:55:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQA-000616-GK
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQA-0003JL-DL
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQA-00088H-CA
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9ELgGl9LtcjZBnUZVP1iesZeIFqIMD4XBne2U90EKt0=; b=WGBWPxBJcVjhOPF/JnlZ7oOzzn
	ACB1hs0HEBN3W3rzVlIiaDPzO14ZD72K0QYLbc47NaZWuj/KzGp88gKrEC6Qnm4PsXi+EiDUA/Ywk
	WvUb5N6qFHrFNfVMVCCEQk894HI8xSH1eJX1eJkVV8xozwwt5R+hQF0JFdxN0tLyeca0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] xen/evtchn: rework per event channel lock
Message-Id: <E1kkGQA-00088H-CA@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:02 +0000

commit 1ad177370df2db9129c97c7305962fc5ad298728
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:31:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:31:01 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 93c4fb9a79..8d1f9a9fc6 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2495,14 +2495,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("d%d:%3d(%c%c%c)%c",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-',
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 9aef7a860a..b4e83e0778 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -660,11 +660,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 97ba8e0795..f782ffeb82 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -85,7 +85,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -114,6 +114,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42387.76197 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQL-00062H-QF; Wed, 02 Dec 2020 00:55:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42387.76197; Wed, 02 Dec 2020 00:55:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQL-000629-Mz; Wed, 02 Dec 2020 00:55:13 +0000
Received: by outflank-mailman (input) for mailman id 42387;
 Wed, 02 Dec 2020 00:55:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQK-000623-Hv
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQK-0003JO-H8
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQK-00088w-G9
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6uMaMVv/kNqr/dJDDj2rRpv/srk5K9izJ0tsy3AXXkA=; b=m1FpGQ212clYYO2VowEE1E1siT
	0UaBXo8/Vtkimbkdx9thiDoaoWxV5hX86mpQrX4ff0/yfqdoNi72R+nFoRPEnpqQoFYjIOqBopIxd
	UCLUdnUEquC30yhCAIIQb8Ab0M9mlqt/b2cnQ/RdKk2B+/ix3xxLNkXGxCF7YDb2haos=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kkGQK-00088w-G9@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:12 +0000

commit d11d9775511e98157a53356c5cf1f37a1bdc9fe0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:32:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:32:18 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index b21c3783d3..a80bcf3e42 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 2dfa1f4295..87ea38b7a0 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 5513f399d5..a314bf85ce 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -281,16 +281,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 722919b762..c14bd07a2b 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -91,8 +91,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42388.76202 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQW-00063b-SC; Wed, 02 Dec 2020 00:55:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42388.76202; Wed, 02 Dec 2020 00:55:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQW-00063R-Oe; Wed, 02 Dec 2020 00:55:24 +0000
Received: by outflank-mailman (input) for mailman id 42388;
 Wed, 02 Dec 2020 00:55:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQU-000639-LR
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQU-0003Jb-KV
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQU-00089U-Jj
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2avHUjLZks78GwYT4+t8s/aOREkDPibvLInCspaXNwU=; b=da0wFTjl2mbya9KopC+aEFoMzl
	avWqvxttPrk48LcjreussJ+ca4GP+1FBLsxKu43/nj7AGkwNVUhOB0Vx8UjD7zSEwDc9rCU/Gqm0P
	45SWc6s2PhfRFYgj4vqsjMlpeDHoAa6C222Y4eutIgdVLszn58CuJVy2/PvVEo+dmxdU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86/vpt: fix build with old gcc
Message-Id: <E1kkGQU-00089U-Jj@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:22 +0000

commit 7c6ee4ee232d2e7b2db1981aa7b9f578a2b0f0ad
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:32:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:32:51 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index d64467b631..ae7f715620 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -401,7 +401,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42389.76205 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQg-00064s-TB; Wed, 02 Dec 2020 00:55:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42389.76205; Wed, 02 Dec 2020 00:55:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQg-00064m-QC; Wed, 02 Dec 2020 00:55:34 +0000
Received: by outflank-mailman (input) for mailman id 42389;
 Wed, 02 Dec 2020 00:55:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQe-00064Y-Oi
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQe-0003KN-Nu
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQe-0008A4-Mz
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qY9GYLA2aMFWf1UHD4bQiutxoWrXSKl5KlMl+VLIi8M=; b=krX01kHI5Um+MubrfSnoGzf7vN
	k1nOTs9Qr8MVfAs0Zr7hQueXbZVOpk5n0Q/3WsFSZzc4zDFJi6j1PIL8EzWe2P6dYyDnAcNJUw5df
	ol/XQ7OVjl3CjMiHEgFe+keVszXc2TICbGkvgatjGhV1GBVDimnd2NWvmVWR+Wm5bhmM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kkGQe-0008A4-Mz@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:32 +0000

commit 1cfb9b1c5b9e4c024f5f139d7a3d0357d2417b13
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:33:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:33:19 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index f782ffeb82..99e2f1aac5 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -117,8 +117,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42390.76209 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQq-00066J-Ur; Wed, 02 Dec 2020 00:55:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42390.76209; Wed, 02 Dec 2020 00:55:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQq-00066B-Rl; Wed, 02 Dec 2020 00:55:44 +0000
Received: by outflank-mailman (input) for mailman id 42390;
 Wed, 02 Dec 2020 00:55:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQo-00065y-S5
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQo-0003KZ-RI
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQo-0008AY-QJ
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6awDcbT3L8Fckz4KtoOsR9dnu0c3bd0zEi+yId/pxkw=; b=WPLYDfafPTIi5IplJnNaqwc32/
	pgqqTHMECi/4v3H27BeCBWKMy/ol2q9Zt3/y3t6pnexEpMNcba4x0rDRI3t4sd24XYyltio2vmmYg
	0qze49XbEDAAbhRWRfP6zZhvY+TqfW28utWmWuhWwBcnwcW7txQXvBqgHzYcRX1SnUQg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86/DMI: fix SMBIOS pointer range check
Message-Id: <E1kkGQo-0008AY-QJ@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:42 +0000

commit 8e6c236c3ef39d68bc3f0d170a1023c4c6914dce
Author:     Jan Beulich <JBeulich@suse.com>
AuthorDate: Tue Dec 1 15:33:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:33:57 2020 +0100

    x86/DMI: fix SMBIOS pointer range check
    
    Forever since its introduction this has been using an inverted relation
    operator.
    
    Fixes: 54057a28f22b ("x86: support SMBIOS v3")
    Signed-off-by: Jan Beulich <JBeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: 6befe598706218673b14710d90d00ce90763b372
    master date: 2020-11-24 11:25:29 +0100
---
 xen/arch/x86/dmi_scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index d24da1c53a..e5930d27ea 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -357,7 +357,7 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 			memcpy_fromio(&smbios3, q, sizeof(smbios3));
 			if (memcmp(smbios3.anchor, "_SM3_", 5) ||
 			    smbios3.length < sizeof(smbios3) ||
-			    q < p + 0x10000 - smbios3.length ||
+			    q > p + 0x10000 - smbios3.length ||
 			    !dmi_checksum(q, smbios3.length))
 				smbios3.length = 0;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:55:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:55:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42391.76213 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGR0-00067N-06; Wed, 02 Dec 2020 00:55:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42391.76213; Wed, 02 Dec 2020 00:55:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGQz-00067F-TM; Wed, 02 Dec 2020 00:55:53 +0000
Received: by outflank-mailman (input) for mailman id 42391;
 Wed, 02 Dec 2020 00:55:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQy-000679-VX
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQy-0003Kk-Ul
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGQy-0008B6-Tt
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:55:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=mLYKr1AT1tEG+t0QHP9etTchhNB1U8PHXNBAWd+iSLE=; b=MjuEojM930Ef8uxhsaQleHsQkz
	bsVQ7Mw6tcBCZXWODaMAqgMZSuEB1AVxg2Ih+UqbDdTMkj3L+ZISJH6Lh6KMaqs+PNY5QN4Gqtsga
	Z0RGNABNF0IH8/uPguO5k/tV8rZAOSnP2qpwUtBW3BLHlvFEkfEHr4RlzHMDHxmm/6Jk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] xen/events: rework fifo queue locking
Message-Id: <E1kkGQy-0008B6-Tt@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:55:52 +0000

commit 72bd989f51878bc9ba61e930b0c29b921a30dc0d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:34:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:34:31 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 00:56:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 00:56:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42392.76217 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGRA-00069g-3c; Wed, 02 Dec 2020 00:56:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42392.76217; Wed, 02 Dec 2020 00:56:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkGRA-00069Y-04; Wed, 02 Dec 2020 00:56:04 +0000
Received: by outflank-mailman (input) for mailman id 42392;
 Wed, 02 Dec 2020 00:56:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGR9-00069O-4N
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:56:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGR9-0003L6-2e
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:56:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkGR9-0008Br-14
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 00:56:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=umnr18z0CaQGe50JVkliu9uuvFVFmaiYQEKBY65D5P8=; b=UcXET97ayFXvyrWFJVyNigvyao
	nAcpEFs3j5CCGfXO3twPTaJHTjdxhc4w+NYmZZfVmduEopL5Ruu4GrNN6UEAPlwKBaHvleBqW8Cq4
	PoeZIDaV01rRU5V6tkbrtGHHhRjc41MSioY99qQECynWtHLm0bQrWYfGFZZ+FewqjvKw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
Message-Id: <E1kkGR9-0008Br-14@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 00:56:03 +0000

commit 1d1d1f5391976456a79daac0dcfe7157da1e54f7
Author:     Roger Pau Monné <roge.rpau@citrix.com>
AuthorDate: Tue Dec 1 15:34:55 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:34:55 2020 +0100

    x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
    
    The usage of idx instead of the GSI in vioapic_write_redirent when
    accessing gsi_assert_count can cause a PVH dom0 with multiple
    vIO-APICs to lose interrupts in case a pin of a IO-APIC different than
    the first one is unmasked with pending interrupts.
    
    Switch to use gsi instead to fix the issue.
    
    Fixes: 9f44b08f7d0e4 ('x86/vioapic: introduce support for multiple vIO APICS')
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Roger Pau Monné <roge.rpau@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 3ae469af8e680df31eecd0a2ac6a83b58ad7ce53
    master date: 2020-11-30 14:06:38 +0100
---
 xen/arch/x86/hvm/vioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index b87facb0e0..52c5c636e3 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -260,7 +260,7 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 0;
     else if ( !ent.fields.mask &&
               !ent.fields.remote_irr &&
-              hvm_irq->gsi_assert_count[idx] )
+              hvm_irq->gsi_assert_count[gsi] )
     {
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 03:44:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 03:44:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42425.76278 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ3j-0003tA-FN; Wed, 02 Dec 2020 03:44:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42425.76278; Wed, 02 Dec 2020 03:44:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ3j-0003t2-CN; Wed, 02 Dec 2020 03:44:03 +0000
Received: by outflank-mailman (input) for mailman id 42425;
 Wed, 02 Dec 2020 03:44:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3i-0003sx-8P
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3i-0005EE-3p
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3i-00051k-2j
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zQy/UIJs/nVu0NyOxQ/2R5TNhwfH+kgBJe21dOaTejc=; b=JPvchFj6GCVvZPMv6l7Ta9UWAz
	/76dvbVxzoMsYmsnC6DXwE3u4W19+zHvCTc5mVMtKWKdJa1oFunq6BJNAdrrB4rXiv5QPHmKXcTyH
	Om0GyJcPV+jELYWJaWLqSI/BFRu17OoRsNZ5ygB4ygu3Bf8R66oARo4gbhXNWD8dLhKA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] xen/evtchn: rework per event channel lock
Message-Id: <E1kkJ3i-00051k-2j@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 03:44:02 +0000

commit 5c15a1cccb8d336eb46a6ca7bda4d9df2d6327a1
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:45:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:45:03 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index f49ce8cf57..29af31a1db 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2371,14 +2371,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 91d44d6f1c..f671ec0d89 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -662,11 +662,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index b918624327..eb8f63da69 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -83,7 +83,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -112,6 +112,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 03:44:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 03:44:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42426.76282 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ3t-0003ty-H6; Wed, 02 Dec 2020 03:44:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42426.76282; Wed, 02 Dec 2020 03:44:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ3t-0003tq-E1; Wed, 02 Dec 2020 03:44:13 +0000
Received: by outflank-mailman (input) for mailman id 42426;
 Wed, 02 Dec 2020 03:44:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3s-0003tj-Ba
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3s-0005EH-9U
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ3s-00054A-73
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xeZY9GuCh4FoGHauRC+obVluMyKXq0V/kw16JUS0U44=; b=uuAdWzQtdNvGV8K2gr87KhkH1j
	ycUb+mACrHYv4f5bvHdrBXGrs+38UcGPFJ7pC0hi38SR43CgMTR8PvK2nGvOsS93GfuzRJBcUr/1m
	FZjQlRPGvfqkEr3TqK4ykuRmQRYPagHZeEhf2M4yam7Z3k4trw+GC8KfSb59iIATYQ+8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kkJ3s-00054A-73@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 03:44:12 +0000

commit 1dd870ec2b6080d67944fd02d2d548716d7551bb
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:46:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:46:00 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 56cfbbe2d8..fc9d6b5bf0 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 7c170f520a..640c708659 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 277fb66e91..3d00c747f6 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -280,16 +280,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 32ecc0ea2a..93386bd7a1 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 03:44:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 03:44:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42427.76286 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ43-0003vj-KG; Wed, 02 Dec 2020 03:44:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42427.76286; Wed, 02 Dec 2020 03:44:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ43-0003vb-H4; Wed, 02 Dec 2020 03:44:23 +0000
Received: by outflank-mailman (input) for mailman id 42427;
 Wed, 02 Dec 2020 03:44:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ42-0003vP-Fd
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ42-0005EP-Em
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ42-00054s-CP
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qsXtRy2umsXu3TCYDjTG29g7OKwAGT/Cz0o2FpsRNaE=; b=UtggTA4kLXj+/mz3RNctc/kSTR
	L314EZDysOXlHRGzEUdPFfISJ8Q7C0StlRTqQ0mg7t6H7XFb+H9FP+ruo5OrSeaDzzg9ZSEtVrh6n
	o3LFmwtRMnbgpNorjfCNNnEYWFzprKv+EGs3kC3e8LtXYlpIRyIoSB80dpAKpG9nD4jg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kkJ42-00054s-CP@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 03:44:22 +0000

commit 40ab01947f10f0ac8cbbb629b83241106bed23e4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:46:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:46:34 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index eb8f63da69..db645102e2 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -115,8 +115,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 03:44:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 03:44:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42428.76290 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ4D-0003x4-M6; Wed, 02 Dec 2020 03:44:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42428.76290; Wed, 02 Dec 2020 03:44:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ4D-0003wu-Ih; Wed, 02 Dec 2020 03:44:33 +0000
Received: by outflank-mailman (input) for mailman id 42428;
 Wed, 02 Dec 2020 03:44:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4C-0003wl-KH
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4C-0005Ey-JJ
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4C-00055Y-HW
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XUfQmlENHVUk1ehmgSbKxjSzV81doE+ZNQRF8K3JaJU=; b=V1KZhyIxXlWWuV8L+JZy8W4Opf
	UP+iew5n5fAulojFlCB9g4tyJULTHo4RCBC4eS+7w3pd3nhB381rc+0Cwd0YDCbUJ01uDaYV0i4+q
	qaSzM5Skjqgh0gCKW10Xjrdn3ORqIS0D7cGOK7pmJT6fE/uwTPQhKVW3wZljVMjvtQmg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] xen/events: rework fifo queue locking
Message-Id: <E1kkJ4C-00055Y-HW@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 03:44:32 +0000

commit 14f577b2dd99944692cba570e6096d08ef00a2c4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:47:26 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:47:26 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 03:44:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 03:44:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42429.76295 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ4N-0003yJ-Nv; Wed, 02 Dec 2020 03:44:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42429.76295; Wed, 02 Dec 2020 03:44:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkJ4N-0003y9-KF; Wed, 02 Dec 2020 03:44:43 +0000
Received: by outflank-mailman (input) for mailman id 42429;
 Wed, 02 Dec 2020 03:44:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4M-0003y1-NK
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4M-0005FA-MS
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkJ4M-00056A-Lh
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 03:44:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dcr72hEjou9sEfVmmX4a9MPWhSvEb8W7HvaWShMPSuM=; b=BSTntRQyItjqYWWOwgAIZaB2ro
	1t2VGp0MBvJDab8t3PRFoL6V6V0q9vQkzhaGQChCQY3ESnfIignuSlADORX3n0TEuFe8WIjjTrQAU
	RS5WrhSCE19eQuVs9gtAR2X1ojCGHxA0EUujCeS/gx4OpOMcvIx4Y8PpyPszPifwQ1VY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] x86/vpt: fix build with old gcc
Message-Id: <E1kkJ4M-00056A-Lh@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 03:44:42 +0000

commit 8145d38b48009255a32ab87a02e481cd09c811f9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:48:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:48:08 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 77b142406f..6d5f98767c 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -400,7 +400,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42459.76347 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyd-00028H-KF; Wed, 02 Dec 2020 07:55:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42459.76347; Wed, 02 Dec 2020 07:55:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyd-000289-HH; Wed, 02 Dec 2020 07:55:03 +0000
Received: by outflank-mailman (input) for mailman id 42459;
 Wed, 02 Dec 2020 07:55:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyc-00027z-8B
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyc-0002Uu-7L
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyc-0008Fv-5I
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+1QFcGyDcxsyY2VVewuuB3UqeJbW4WZO9eGqTTDkNyY=; b=0lzpqQ1noLfzbLiagwV5wI4MII
	vYA6Bp+XKdYKZdlHDvKd6CsSIqQnGvvCw7R2acDMpxmeMERNJSF4/Oz/TRe7yZ08W6Ky67x1Gd0so
	3lNUKLN+FUD0k6h5xD0jFz0geACLQMMJZuVftnFiJeTTmXZIDjyXvwyM1hO5G6MH7p5k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] update Xen version to 4.13.3-pre
Message-Id: <E1kkMyc-0008Fv-5I@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:02 +0000

commit ec092152be2c0a834a575eaff71d70cc1de882e9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 13:54:02 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 13:54:02 2020 +0100

    update Xen version to 4.13.3-pre
---
 xen/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/Makefile b/xen/Makefile
index 4a7709bd5c..0fe43409a8 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 13
-export XEN_EXTRAVERSION ?= .2$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .3-pre$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42461.76352 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyn-00029b-Mz; Wed, 02 Dec 2020 07:55:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42461.76352; Wed, 02 Dec 2020 07:55:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyn-00029S-Iw; Wed, 02 Dec 2020 07:55:13 +0000
Received: by outflank-mailman (input) for mailman id 42461;
 Wed, 02 Dec 2020 07:55:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMym-00029H-CY
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMym-0002Ux-BG
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMym-0008GT-AK
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=D5kYOfrgKZpIpVVBQYEAfzGq5lZMe0YetdLYHXZaN2E=; b=wEbjmdogWW+mrwS0TEfTeAUl4k
	BZxEXLC7jOlYBcmByBXkjUrTEthrMuUWfe+sVG95OPrxXCC1Ttmsjq7saO8rizQHqVWv0q4P6DHZQ
	T4PDf08Z+uin0bmmw22wA3Lo2i/sV4YV3tFDghSYp1/9ThY/uYhB9thrINUCINsVSN/k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] xen/evtchn: rework per event channel lock
Message-Id: <E1kkMym-0008GT-AK@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:12 +0000

commit 7d6f52d47b3d3ec9f0bec8b34e7f1a0e639849e8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:36:36 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:36:36 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index bb95583742..f05defbd7d 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2481,14 +2481,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("d%d:%3d(%c%c%c)%c",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-',
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index bbecbfa16f..36a7e30605 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -660,11 +660,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 12f666cb79..181e5abaa6 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -434,14 +459,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -458,7 +483,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( domain_vcpu(d, vcpu) == NULL )
         return -ENOENT;
@@ -470,13 +494,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -520,7 +544,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -553,14 +576,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -581,7 +604,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -681,14 +703,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -696,9 +718,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -718,7 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -731,7 +752,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -766,7 +787,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -793,9 +814,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -824,9 +847,11 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -836,7 +861,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -851,9 +875,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1050,15 +1076,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1304,7 +1332,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1317,14 +1344,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1356,7 +1383,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1371,7 +1397,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1381,7 +1408,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index fa93a3684a..6588333f42 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -111,6 +111,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -244,11 +259,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -263,11 +277,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 8bb5bd7b38..89a9df5a63 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -83,7 +83,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -112,6 +112,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42462.76356 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyx-0002BH-Qm; Wed, 02 Dec 2020 07:55:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42462.76356; Wed, 02 Dec 2020 07:55:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMyx-0002B5-Me; Wed, 02 Dec 2020 07:55:23 +0000
Received: by outflank-mailman (input) for mailman id 42462;
 Wed, 02 Dec 2020 07:55:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyw-0002At-GP
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyw-0002V5-Fe
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMyw-0008HQ-Du
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=u58P0Two8iEDMiSGAUj9S9xWSnCNRubzokC1Rsmg/Aw=; b=spXo+MruSigl+jbUYBEZ4PtBog
	4ieN3ZxWouhTEvwKlG6Kn91DteDwbAIiDI8xX90Jl3/OHLgUNMTwPaiOiEbkvqABVDeFENbBJGyiT
	ub0R94q25B0SRcEHOfglMRDbxOAGzzZFtI7QPudehVVV7Mxk2azgDYARZ+jxENZgr+4Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kkMyw-0008HQ-Du@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:22 +0000

commit 72031bcf69726efd05e34732b62a0f51ff2a257d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:37:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:37:39 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 181e5abaa6..45852c07ba 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -744,12 +744,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 2ba3ec95b4..e22d6160b5 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 2dfa1f4295..87ea38b7a0 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 794f465321..cf7f25cda2 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -280,16 +280,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 722919b762..c14bd07a2b 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -91,8 +91,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42463.76359 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMz7-0002Ce-RK; Wed, 02 Dec 2020 07:55:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42463.76359; Wed, 02 Dec 2020 07:55:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMz7-0002CW-OF; Wed, 02 Dec 2020 07:55:33 +0000
Received: by outflank-mailman (input) for mailman id 42463;
 Wed, 02 Dec 2020 07:55:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMz6-0002CO-Kf
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMz6-0002VC-Js
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMz6-0008IC-I6
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=snGk5ICf8u9DCD3/NSRLA5IRAy/Mkj0HYhLSz4LTFRc=; b=E2hakXSyf2ah3a79tKP9mQ0WSS
	8mYkW7+al0kVt1rD0OL72v8lAoteQb4ywtFvXtLlYboZWMmTtoSLCHsX5Uwpt5Qrd2junqXSGliu5
	sNYkja+15TTh8kL/TFj7rbI452u3SjkwbiZF/GgPWovmVIyVPIzTY4ySytqNklkPe7MY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86/vpt: fix build with old gcc
Message-Id: <E1kkMz6-0008IC-I6@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:32 +0000

commit 4f30743fdf815450bc9c052f2746751265a01aa4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 15:38:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:38:23 2020 +0100

    x86/vpt: fix build with old gcc
    
    I believe it was the XSA-336 fix (42fcdd42328f "x86/vpt: fix race when
    migrating timers between vCPUs") which has unmasked a bogus
    uninitialized variable warning. This is observable with gcc 4.3.4, but
    only on 4.13 and older; it's hidden on newer versions apparently due to
    the addition to _read_unlock() done by 12509bbeb9e3 ("rwlocks: call
    preempt_disable() when taking a rwlock").
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: f2c620aa062767b318267d678ae249dcb637b870
    master date: 2020-11-18 12:38:01 +0100
---
 xen/arch/x86/hvm/vpt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 77b142406f..6d5f98767c 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -400,7 +400,7 @@ int pt_update_irq(struct vcpu *v)
                  * associated with the timer.
                  */
                 time_cb *cb = NULL;
-                void *cb_priv;
+                void *cb_priv = NULL;
 
                 pt_vcpu_lock(v);
                 /* Make sure the timer is still on the list. */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42464.76363 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzH-0002Dr-Sp; Wed, 02 Dec 2020 07:55:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42464.76363; Wed, 02 Dec 2020 07:55:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzH-0002Dj-Pm; Wed, 02 Dec 2020 07:55:43 +0000
Received: by outflank-mailman (input) for mailman id 42464;
 Wed, 02 Dec 2020 07:55:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzG-0002Dc-Nz
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzG-0002W9-ND
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzG-0008Io-ML
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Jj2i+upSRufzcyeq8EIy4aARqZN5k6O2zOJVMVoegCw=; b=ZXE2F/IayZqhG/aSyEs0SS8f2I
	MdHo1+k89aMru4O9gz72QxRzniCgUf7krLzUwAgKgRDSD5uKkF+r0Dcmxei4vlf7qF6pWKC1WWwwa
	jmg6RVNCZOLnK+7bb43RNBFANdUVuRSu4Q8usLa2lbJQJ3oIIedOc4XyDuf4T88mwwJo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kkMzG-0008Io-ML@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:42 +0000

commit d064b6581bbddf9ef4a8817a2f077dd2a0afa1da
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:39:02 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:39:02 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 27ab3a1c3f..2037b24196 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -65,16 +73,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -225,8 +235,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 89a9df5a63..8bf1b90261 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -115,8 +115,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:55:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:55:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42465.76367 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzR-0002FA-UL; Wed, 02 Dec 2020 07:55:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42465.76367; Wed, 02 Dec 2020 07:55:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzR-0002F2-RO; Wed, 02 Dec 2020 07:55:53 +0000
Received: by outflank-mailman (input) for mailman id 42465;
 Wed, 02 Dec 2020 07:55:52 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzQ-0002Et-SB
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzQ-0002WK-Qc
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzQ-0008JW-Pg
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:55:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=j/8rtIRK4uDNCNGo7Kp8FJBWjlhAvvQSeiJsLq0XPFM=; b=aBr22rNOzyQhiVn7yGzXO+HOKM
	T5PaRj6jialbzYtDLuAuGrAwwZ6OyD3Czo8gTd0jbzFuaxhe6enlI/QhJyfAeyTXQLkHcgwA8Kv3T
	Cc7a2vxxJm9/bQc0h0MwIK7jW27SvsmONhDPsXHmcNaltu2vC7LGgjhRWlRZsyMnJulI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86/DMI: fix SMBIOS pointer range check
Message-Id: <E1kkMzQ-0008JW-Pg@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:55:52 +0000

commit a1d8a6c24b87ff86072d071376587ac68211c6e7
Author:     Jan Beulich <JBeulich@suse.com>
AuthorDate: Tue Dec 1 15:39:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:39:48 2020 +0100

    x86/DMI: fix SMBIOS pointer range check
    
    Forever since its introduction this has been using an inverted relation
    operator.
    
    Fixes: 54057a28f22b ("x86: support SMBIOS v3")
    Signed-off-by: Jan Beulich <JBeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    master commit: 6befe598706218673b14710d90d00ce90763b372
    master date: 2020-11-24 11:25:29 +0100
---
 xen/arch/x86/dmi_scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index d24da1c53a..e5930d27ea 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -357,7 +357,7 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 			memcpy_fromio(&smbios3, q, sizeof(smbios3));
 			if (memcmp(smbios3.anchor, "_SM3_", 5) ||
 			    smbios3.length < sizeof(smbios3) ||
-			    q < p + 0x10000 - smbios3.length ||
+			    q > p + 0x10000 - smbios3.length ||
 			    !dmi_checksum(q, smbios3.length))
 				smbios3.length = 0;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:56:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:56:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42466.76370 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzd-0002Gc-0Q; Wed, 02 Dec 2020 07:56:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42466.76370; Wed, 02 Dec 2020 07:56:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzc-0002GN-Sz; Wed, 02 Dec 2020 07:56:04 +0000
Received: by outflank-mailman (input) for mailman id 42466;
 Wed, 02 Dec 2020 07:56:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMza-0002GB-Uq
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMza-0002Wg-U3
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMza-0008KL-T8
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WVHXEE7Kr0x9btZiiAe7Lr5W0mAQPrTJ42+mf94+MGg=; b=P7cqLjo3864HqTlBHupCEJGcWj
	A+nYmTGfmUUDxrq09bUoE/yv0S5GOG1ZQFUpRbD7aNk3hForkw7jj2NIl+3IWyNpt7p+gP6/vJCI3
	mWv82iCj+X6Lw2SwNcFArDMlA+xrQr0ES8AkA0UlITa15lmn9x3Do7q90CeVBTS5jsC4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] xen/events: rework fifo queue locking
Message-Id: <E1kkMza-0008KL-T8@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:56:02 +0000

commit 74c5729bb33d25eb2c6a5ea1fd9936d9798bb74c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 15:40:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:40:24 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2037b24196..2f5e868b7a 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -66,38 +66,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -169,6 +137,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -183,17 +154,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -204,25 +225,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -241,8 +248,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -255,6 +262,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -263,15 +271,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 07:56:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 07:56:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42467.76375 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzn-0002IX-3w; Wed, 02 Dec 2020 07:56:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42467.76375; Wed, 02 Dec 2020 07:56:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkMzn-0002IP-0r; Wed, 02 Dec 2020 07:56:15 +0000
Received: by outflank-mailman (input) for mailman id 42467;
 Wed, 02 Dec 2020 07:56:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzl-0002IF-1y
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzl-0002Wp-1E
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkMzl-0008LE-0L
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 07:56:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=lo2/x6y4yAjsvjNFHzIZJU3pjTUwqQk+eCSSZj3RCdA=; b=NcBNY+b0lTTPUl9fjPcoUWTd1F
	7L3PzEw5alu7eCuq86iLk7YMHUeAexY95aEKBG/2MGQlCvOcSvymctdLuCfOROMoLvA2EecNSuqSc
	QtX7ghkneKOKuYx044VFuUb/ZrrvmENIWnR53USHnbi8VijrsBBYO51L397aLQGiDnJ4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
Message-Id: <E1kkMzl-0008LE-0L@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 07:56:13 +0000

commit b5302273e2c51940172400486644636f2f4fc64a
Author:     Roger Pau Monné <roge.rpau@citrix.com>
AuthorDate: Tue Dec 1 15:41:07 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 15:41:07 2020 +0100

    x86/vioapic: fix usage of index in place of GSI in vioapic_write_redirent
    
    The usage of idx instead of the GSI in vioapic_write_redirent when
    accessing gsi_assert_count can cause a PVH dom0 with multiple
    vIO-APICs to lose interrupts in case a pin of a IO-APIC different than
    the first one is unmasked with pending interrupts.
    
    Switch to use gsi instead to fix the issue.
    
    Fixes: 9f44b08f7d0e4 ('x86/vioapic: introduce support for multiple vIO APICS')
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Roger Pau Monné <roge.rpau@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 3ae469af8e680df31eecd0a2ac6a83b58ad7ce53
    master date: 2020-11-30 14:06:38 +0100
---
 xen/arch/x86/hvm/vioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 9aeef32a14..d899dd9707 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -260,7 +260,7 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 0;
     else if ( !ent.fields.mask &&
               !ent.fields.remote_irr &&
-              hvm_irq->gsi_assert_count[idx] )
+              hvm_irq->gsi_assert_count[gsi] )
     {
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 09:22:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 09:22:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42501.76432 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOKs-0002ut-S6; Wed, 02 Dec 2020 09:22:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42501.76432; Wed, 02 Dec 2020 09:22:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOKs-0002ul-PD; Wed, 02 Dec 2020 09:22:06 +0000
Received: by outflank-mailman (input) for mailman id 42501;
 Wed, 02 Dec 2020 09:22:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOKr-0002ug-Hf
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOKr-0004pu-Dr
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOKr-0006C2-CT
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AoaEcWY9guLBZQCLZnKe3tSOKVDadWIhOwi1hHnVlII=; b=gFWT4gDih5Jr7Yrmg2MWOaTl+8
	/103iPIyWDFexhzOqU0eMrAQ4Tdmroz2NxtGvN1JTlv1I0r2fWCYZT7jC0xbCH8Rcx/TM8tQSZn5j
	JCMEldjNNf9pVjC2EySxs9zDvGMJVtOjVPIDtbX9CNjvK/zLTITv2MZPkeJrFtk7ad/Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] ns16550: gate all PCI code with CONFIG_X86
Message-Id: <E1kkOKr-0006C2-CT@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 09:22:05 +0000

commit b00d0576723fa2155c0c8f5345a40335e0bc3912
Author:     Rahul Singh <rahul.singh@arm.com>
AuthorDate: Wed Dec 2 10:09:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:09:27 2020 +0100

    ns16550: gate all PCI code with CONFIG_X86
    
    The NS16550 driver is assuming that NS16550 PCI card are usable if the
    architecture supports PCI (i.e. CONFIG_HAS_PCI=y). However, the code is
    very x86 focus and will fail to build on Arm (/!\ it is not all the
    errors):
    
    ns16550.c: In function ‘ns16550_init_irq’:
    ns16550.c:726:21: error: implicit declaration of function ‘create_irq’;
    did you mean ‘release_irq’? [-Werror=implicit-function-declaration]
              uart->irq = create_irq(0, false);
                          ^~~~~~~~~~
                          release_irq
    ns16550.c:726:21: error: nested extern declaration of ‘create_irq’
    [-Werror=nested-externs]
    ns16550.c: In function ‘ns16550_init_postirq’:
    ns16550.c:768:33: error: ‘mmio_ro_ranges’ undeclared (first use in this
    function); did you mean ‘mmio_handler’?
                   rangeset_add_range(mmio_ro_ranges, uart->io_base,
                                      ^~~~~~~~~~~~~~
                                      mmio_handler
    ns16550.c:768:33: note: each undeclared identifier is reported only once
    for each function it appears in
    ns16550.c:780:20: error: variable ‘msi’ has initializer but incomplete
    type
                  struct msi_info msi = {
                         ^~~~~~~~
    
    Enabling support for NS16550 PCI card on Arm would require more plumbing
    in addition to fixing the compilation error.
    
    Arm systems tend to have platform UART available such as NS16550, PL011.
    So there are limited reasons to get NS16550 PCI support for now on Arm.
    
    Guard all remaining PCI code that is not under x86 flag with CONFIG_X86.
    
    No functional change intended.
    
    Signed-off-by: Rahul Singh <rahul.singh@arm.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Stefano Stabellini <sstabellini@kernel.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/drivers/char/ns16550.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 9235d854fe..16a73d0c0e 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -8,6 +8,15 @@
  * Copyright (c) 2003-2005, K A Fraser
  */
 
+/*
+ * The PCI part of the code in this file currently is only known to
+ * work on x86. Undo this hack once the logic has been suitably
+ * abstracted.
+ */
+#if defined(CONFIG_HAS_PCI) && defined(CONFIG_X86)
+# define NS16550_PCI
+#endif
+
 #include <xen/console.h>
 #include <xen/init.h>
 #include <xen/irq.h>
@@ -16,7 +25,7 @@
 #include <xen/timer.h>
 #include <xen/serial.h>
 #include <xen/iocap.h>
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 #include <xen/pci_ids.h>
@@ -51,7 +60,7 @@ static struct ns16550 {
     unsigned int timeout_ms;
     bool_t intr_works;
     bool_t dw_usr_bsy;
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     /* PCI card parameters. */
     bool_t pb_bdf_enable;   /* if =1, pb-bdf effective, port behind bridge */
     bool_t ps_bdf_enable;   /* if =1, ps_bdf effective, port on pci card */
@@ -66,7 +75,7 @@ static struct ns16550 {
 #endif
 } ns16550_com[2] = { { 0 } };
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
 struct ns16550_config {
     u16 vendor_id;
     u16 dev_id;
@@ -256,7 +265,7 @@ static int ns16550_getc(struct serial_port *port, char *pc)
 
 static void pci_serial_early_init(struct ns16550 *uart)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
         return;
 
@@ -355,7 +364,7 @@ static void __init ns16550_init_preirq(struct serial_port *port)
 
 static void __init ns16550_init_irq(struct serial_port *port)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     struct ns16550 *uart = port->uart;
 
     if ( uart->msi )
@@ -397,7 +406,7 @@ static void __init ns16550_init_postirq(struct serial_port *port)
     uart->timeout_ms = max_t(
         unsigned int, 1, (bits * uart->fifo_size * 1000) / uart->baud);
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( uart->bar || uart->ps_bdf_enable )
     {
         if ( uart->param && uart->param->mmio &&
@@ -477,7 +486,7 @@ static void ns16550_suspend(struct serial_port *port)
 
     stop_timer(&uart->timer);
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( uart->bar )
        uart->cr = pci_conf_read16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
                                   uart->ps_bdf[2]), PCI_COMMAND);
@@ -486,7 +495,7 @@ static void ns16550_suspend(struct serial_port *port)
 
 static void _ns16550_resume(struct serial_port *port)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     struct ns16550 *uart = port->uart;
 
     if ( uart->bar )
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 09:22:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 09:22:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42510.76531 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOL4-0003E3-SC; Wed, 02 Dec 2020 09:22:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42510.76531; Wed, 02 Dec 2020 09:22:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOL3-0003DC-Vd; Wed, 02 Dec 2020 09:22:17 +0000
Received: by outflank-mailman (input) for mailman id 42510;
 Wed, 02 Dec 2020 09:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOL1-00037q-IE
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOL1-0004qo-Gx
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOL1-0006DE-GK
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=UhxShQ4SKWap9j0m0f3yxsiYDW6H3CbBuXmLeHexh/8=; b=EbZq25488p1Faf1hRzxLWqkbSH
	1VtJkSnRK5tXom8YEJjXQco/DpW5UO6ODL5AjZmaWJqZccLSXYqdvqqJsrHqdKawFLRC0gJbRn6bd
	8/yqtxBx8KjMP/QRKiVT8eruYbkP8u7S8BNrQgR1aH7Nq5uEFW7V2sXNtYPEt9hRhlx4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: add cpu to sched_res_mask when removing it from cpupool
Message-Id: <E1kkOL1-0006DE-GK@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 09:22:15 +0000

commit 9f5ce6e5953456d499e05b48db1de5724d4b09de
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:12:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:12:04 2020 +0100

    xen/cpupool: add cpu to sched_res_mask when removing it from cpupool
    
    When a cpu is removed from a cpupool and added to the free cpus it
    should be added to sched_res_mask, too.
    
    The related removal from sched_res_mask in case of core scheduling
    is already done in schedule_cpu_add().
    
    As long as all cpupools share the same scheduling granularity there
    is nothing going wrong with the missing addition, but this will change
    when per-cpupool granularity is fully supported.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index ed973e90ec..f8c81592af 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -3189,6 +3189,7 @@ int schedule_cpu_rm(unsigned int cpu)
             /* Adjust cpu masks of resources (old and new). */
             cpumask_clear_cpu(cpu_iter, sr->cpus);
             cpumask_set_cpu(cpu_iter, sr_new[idx]->cpus);
+            cpumask_set_cpu(cpu_iter, &sched_res_mask);
 
             /* Init timer. */
             init_timer(&sr_new[idx]->s_timer, s_timer_fn, NULL, cpu_iter);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 09:22:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 09:22:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42513.76561 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLD-0003aw-7a; Wed, 02 Dec 2020 09:22:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42513.76561; Wed, 02 Dec 2020 09:22:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLD-0003ai-0L; Wed, 02 Dec 2020 09:22:27 +0000
Received: by outflank-mailman (input) for mailman id 42513;
 Wed, 02 Dec 2020 09:22:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLB-0003Xh-Ku
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLB-0004rJ-K2
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLB-0006EA-JK
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XyoNcc8ej35BJimclRUxXNhbVPdsZdjSa8UXN0Y7nog=; b=YCgDezVtMecZPp9xZ6qncsH3fM
	CH9HmHDprWo4vZdQzrLIHyWbtdxXApzo7vJ9X4sV8dN3JjYsVZwYhpygODLspvHZRZ/WaekI4neEn
	L/Lttj8q6RKFoGv+Rnzg6JXpxXnIW0Mc1i53VEvPFntf8As7oGX4s/D+o+uMjmzD3Q/Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: add missing bits for per-cpupool scheduling granularity
Message-Id: <E1kkOLB-0006EA-JK@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 09:22:25 +0000

commit 1283ad87c6314daed6e9e7af2ab5202d96276202
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:12:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:12:37 2020 +0100

    xen/cpupool: add missing bits for per-cpupool scheduling granularity
    
    Even with storing the scheduling granularity in struct cpupool there
    are still a few bits missing for being able to have cpupools with
    different granularity (apart from the missing interface for setting
    the individual granularities): the number of cpus in a scheduling
    unit is always taken from the global sched_granularity variable.
    
    So store the value in struct cpupool and use that instead of
    sched_granularity.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 3 ++-
 xen/common/sched/private.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 7ea641ca26..6429c8f7b5 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -151,7 +151,7 @@ static void __init cpupool_gran_init(void)
 
 unsigned int cpupool_get_granularity(const struct cpupool *c)
 {
-    return c ? sched_granularity : 1;
+    return c ? c->sched_gran : 1;
 }
 
 static void free_cpupool_struct(struct cpupool *c)
@@ -289,6 +289,7 @@ static struct cpupool *cpupool_create(
     }
     c->sched->cpupool = c;
     c->gran = opt_sched_granularity;
+    c->sched_gran = sched_granularity;
 
     *q = c;
 
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index df50976eb2..685992cab9 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -514,6 +514,7 @@ struct cpupool
     struct scheduler *sched;
     atomic_t         refcnt;
     enum sched_gran  gran;
+    unsigned int     sched_gran;     /* Number of cpus per sched-item. */
 };
 
 static inline cpumask_t *cpupool_domain_master_cpumask(const struct domain *d)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 09:22:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 09:22:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42537.76565 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLN-0003pK-5p; Wed, 02 Dec 2020 09:22:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42537.76565; Wed, 02 Dec 2020 09:22:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLN-0003pC-2B; Wed, 02 Dec 2020 09:22:37 +0000
Received: by outflank-mailman (input) for mailman id 42537;
 Wed, 02 Dec 2020 09:22:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLL-0003o9-O3
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLL-0004rV-NA
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLL-0006Eo-MU
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/Y2pBEJwIuoLxMvm87iI6DopDYkyZBbS63Ung5nFQas=; b=EIC3hWkQ5JHASsYf4iQG4gkNSE
	K1xAtr+b+cJgvg+CosdLegRrZcXcVa5A0b6RzpGueOhs2lKPaZJHjVm6JLbC0jcJbaOA+kExJ7dVu
	OfuqwbaZ5T/e9A0tuaerxji/fOqzE/46vmxVHNEJQ9Cvyqn1DbKeH8NQfSdTZlc6miB4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: sort included headers in cpupool.c
Message-Id: <E1kkOLL-0006Eo-MU@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 09:22:35 +0000

commit b2a88b2e09611f0050ab33767cb878a83171c4bc
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:13:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:13:09 2020 +0100

    xen/cpupool: sort included headers in cpupool.c
    
    Common style is to include header files in alphabetical order. Sort the
    #include statements in cpupool.c accordingly.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 6429c8f7b5..84f326ea63 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -11,15 +11,15 @@
  * (C) 2009, Juergen Gross, Fujitsu Technology Solutions
  */
 
-#include <xen/lib.h>
-#include <xen/init.h>
+#include <xen/cpu.h>
 #include <xen/cpumask.h>
+#include <xen/init.h>
+#include <xen/keyhandler.h>
+#include <xen/lib.h>
 #include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
 #include <xen/warning.h>
-#include <xen/keyhandler.h>
-#include <xen/cpu.h>
 
 #include "private.h"
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 09:22:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 09:22:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42548.76570 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLX-0003u1-7G; Wed, 02 Dec 2020 09:22:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42548.76570; Wed, 02 Dec 2020 09:22:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkOLX-0003ts-3i; Wed, 02 Dec 2020 09:22:47 +0000
Received: by outflank-mailman (input) for mailman id 42548;
 Wed, 02 Dec 2020 09:22:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLV-0003tT-R4
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLV-0004s8-QJ
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkOLV-0006FQ-PY
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 09:22:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=coOyVa0J7+feSRHZZinzmAxcrxjqDYRULQxD3/TgMgQ=; b=b96M/vWSzyT4BFQ/Lo/fPHB4/2
	BnIsqlGV3Uyyq9se6FEl1oeZpkJ+3mJJz3gkK3FV66a6gMERmcS1UJY7M7GWz3pNKwKT3MnYC0umR
	fvNV2CPIlGcyPEH0ljasCtQKn7YNxOEbUVwV4KGAwlt7z8jzhTQO4f3yAIRq/C+nzQdo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs: fix hypfs path documentation
Message-Id: <E1kkOLV-0006FQ-PY@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 09:22:45 +0000

commit cabf60fc32d4cfa1d74a2bdfcdb294a31da5d68e
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:13:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:13:52 2020 +0100

    docs: fix hypfs path documentation
    
    The /params/* entry is missing a writable tag.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/hypfs-paths.pandoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc
index dddb592bc5..6c7b2f7ee3 100644
--- a/docs/misc/hypfs-paths.pandoc
+++ b/docs/misc/hypfs-paths.pandoc
@@ -179,7 +179,7 @@ The minor version of Xen.
 
 A directory of runtime parameters.
 
-#### /params/*
+#### /params/* [w]
 
 The individual parameters. The description of the different parameters can be
 found in `docs/misc/xen-command-line.pandoc`.
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 11:22:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 11:22:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42648.76735 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQCx-0008Fb-Rk; Wed, 02 Dec 2020 11:22:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42648.76735; Wed, 02 Dec 2020 11:22:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQCx-0008FT-O1; Wed, 02 Dec 2020 11:22:03 +0000
Received: by outflank-mailman (input) for mailman id 42648;
 Wed, 02 Dec 2020 11:22:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQCw-0008FO-Fw
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQCw-0007Qz-EA
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQCw-0005CO-Bn
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xO8v2mj7OkJZRILJXGGzAP4B9XFt+kCRswQCyckBgaQ=; b=eLX+S4DXYEfo8ht0LwrJlqB0v3
	QaS6eWfEUrhWcSuSafddOcyFFXClAYd+W+LZBfKRIZZckkrCih/jcwxL8/xPJeSo+89t5iCUdL47N
	29jTQ1iwMzhF+AEE1R2BA6UWH0hCzZDILthchzOsC8RpDgAJJTKnt9w9DUTaZgKB5dfU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] evtchn/fifo: use stable fields when recording "last queue" information
Message-Id: <E1kkQCw-0005CO-Bn@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 11:22:02 +0000

commit 2a730d5b6ad1ea95c3d67fa12ab0091d32b29505
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 17:03:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:03:12 2020 +0100

    evtchn/fifo: use stable fields when recording "last queue" information
    
    Both evtchn->priority and evtchn->notify_vcpu_id could change behind the
    back of evtchn_fifo_set_pending(), as for it - in the case of
    interdomain channels - only the remote side's per-channel lock is held.
    Neither the queue's priority nor the vCPU's vcpu_id fields have similar
    properties, so they seem better suited for the purpose. In particular
    they reflect the respective evtchn fields' values at the time they were
    used to determine queue and vCPU.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    master commit: 6f6f07b64cbe90e54f8e62b4d6f2404cf5306536
    master date: 2020-10-02 08:37:35 +0200
---
 xen/common/event_fifo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 45c024739d..98742ba9cb 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -224,8 +224,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = evtchn->notify_vcpu_id;
-            evtchn->last_priority = evtchn->priority;
+            evtchn->last_vcpu_id = v->vcpu_id;
+            evtchn->last_priority = q->priority;
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 11:22:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 11:22:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42649.76739 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQD7-0008HA-TY; Wed, 02 Dec 2020 11:22:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42649.76739; Wed, 02 Dec 2020 11:22:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQD7-0008H2-Q9; Wed, 02 Dec 2020 11:22:13 +0000
Received: by outflank-mailman (input) for mailman id 42649;
 Wed, 02 Dec 2020 11:22:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQD6-0008GF-JO
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQD6-0007R5-I8
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQD6-0005D6-Gx
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=TrydH+mIbZ5zGEduQ+5EJP3K+7m1xT0Xci9934SaV/A=; b=E2F0L5WGYH9pvaSrWlgDbdZ6zr
	vQM0WkS4jaDA+fVmFGEKwiykJ7sjxEws8N2wrsIZbMhm7X8Vv1j3PspYzXWbS0ey++fO8AeEMtJl5
	JQM6TwFzG4Jx70fIkdQwOsb8foHOQf1Qzi2tGKb9zEVU2fpD45YTImXTWARrhr3Xe3p0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] xen/evtchn: rework per event channel lock
Message-Id: <E1kkQD6-0005D6-Gx@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 11:22:12 +0000

commit 4438fc14a6c60b265a47c780d6a61d4f3015a297
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:04:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:04:43 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 9878486073..a293270cf2 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2331,14 +2331,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 4b7d498c00..f8883bd102 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -616,11 +616,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 0066c8a87f..7f2ad9d826 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -131,7 +165,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -249,7 +283,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -265,14 +298,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -285,32 +318,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -320,7 +347,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -356,7 +382,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -373,7 +399,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -396,7 +422,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -429,14 +454,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -453,7 +478,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
          (d->vcpu[vcpu] == NULL) )
@@ -466,13 +490,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -516,7 +540,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -549,14 +572,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -577,7 +600,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -677,14 +699,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -692,9 +714,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -714,7 +736,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -727,7 +748,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -762,7 +783,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -789,9 +810,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -820,9 +843,11 @@ static void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -832,7 +857,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -847,9 +871,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1044,15 +1070,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1298,7 +1326,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1311,14 +1338,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1350,7 +1377,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1365,7 +1391,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1375,7 +1402,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 87a4aade86..b0c39d402c 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -103,6 +103,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -236,11 +251,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -255,11 +269,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 7e4ad5d51b..3c1284c3da 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -82,7 +82,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -111,6 +111,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 11:22:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 11:22:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42650.76743 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDI-0008In-0A; Wed, 02 Dec 2020 11:22:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42650.76743; Wed, 02 Dec 2020 11:22:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDH-0008Ie-TI; Wed, 02 Dec 2020 11:22:23 +0000
Received: by outflank-mailman (input) for mailman id 42650;
 Wed, 02 Dec 2020 11:22:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDG-0008IV-Ni
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDG-0007RE-Mt
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDG-0005Dk-L2
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cHgLDlbWQ/e5kzQiahHjTkSsHwQar7jfQjGn0i3HonI=; b=VdL0VhZKdZ3UcAcahvnJYgTSt1
	+c6VUgiQIoVr7N4mNtxoFqWxbFYgg2j7hgUtG/61jtbNnI3RbV4W7MobcExIdI2GTdk9sQNaOjvg+
	ojk7H0uqAEAaICaD2HLOiDGrIdQ9bfCz3ZAkV0UR9IvwcnDbm/qaGm2wnthHVRnHNN5s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kkQDG-0005Dk-L2@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 11:22:22 +0000

commit 4fe13265f99fb450085c07037a6096fa5e44351b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:05:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:05:27 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 7f2ad9d826..26198184b1 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -740,12 +740,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index a670880106..2779819e1e 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 8917329225..a3e6108a34 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 17aa543fca..78bc32602e 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -278,16 +278,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 8426b36c72..bfc69f4acd 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 11:22:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 11:22:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42651.76747 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDS-0008KH-1o; Wed, 02 Dec 2020 11:22:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42651.76747; Wed, 02 Dec 2020 11:22:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDR-0008KA-V4; Wed, 02 Dec 2020 11:22:33 +0000
Received: by outflank-mailman (input) for mailman id 42651;
 Wed, 02 Dec 2020 11:22:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDQ-0008Jy-S0
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDQ-0007RQ-RF
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDQ-0005ER-PO
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vDlEKlidK2XcEbDTvkC9v95pX5Xl+JtcMgQyxEAgIOE=; b=nFoux75WMLz4BBMIZIVmoL4qkd
	1EJTtngTxNqgge/423w2JA7JOZdStL9NBhTA7L6UBtuSRqR9HnEEoUtZ9JMAH6pWCFqWFyCPWuPYz
	R+Z9iZfoGekmwlO6SZP2FKjW3J6fJgYuTsFfVv4/nJ8S7eo7X3kyQCMsaYNEik352V3k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kkQDQ-0005ER-PO@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 11:22:32 +0000

commit 8ab4af91fab6618994e5857b65aec5896915d9c5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:06:15 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:06:15 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 98742ba9cb..b1951a29ad 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -64,16 +72,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -224,8 +234,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 3c1284c3da..81af1209dd 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -114,8 +114,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 11:22:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42652.76751 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDc-0008Lf-4L; Wed, 02 Dec 2020 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42652.76751; Wed, 02 Dec 2020 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkQDc-0008LX-0h; Wed, 02 Dec 2020 11:22:44 +0000
Received: by outflank-mailman (input) for mailman id 42652;
 Wed, 02 Dec 2020 11:22:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDa-0008LO-Vg
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDa-0007Ry-Ut
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkQDa-0005F5-To
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 11:22:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LYO4pgasfU6m2S7FWqBrqv3vEGiFxG3AF7bRmqIykvw=; b=w0LT7FHIRzaCGP5IGxrod1QihD
	lOahAzf3vje0NjCDOBiKIvOagG0EiHxuqCT+l4UieFijCt26oK8Ck495A7VBIRfjDYwviPRsHdL0b
	/D3ecFWF3irvAbXmYeeC/lMUorOfLzCAIwDuaWpphp6AVZYjKMiqQ2delL9YfE/rPdZE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] xen/events: rework fifo queue locking
Message-Id: <E1kkQDa-0005F5-To@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 11:22:42 +0000

commit 41a822c3926350f26917d747c8dfed1c44a2cf42
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:07:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:07:03 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index b1951a29ad..0a90a8404d 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -65,38 +65,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -168,6 +136,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -182,17 +153,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -203,25 +224,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -240,8 +247,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -254,6 +261,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -262,15 +270,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 13:44:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 13:44:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42727.76872 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQN-0005OS-Kh; Wed, 02 Dec 2020 13:44:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42727.76872; Wed, 02 Dec 2020 13:44:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQN-0005OK-HT; Wed, 02 Dec 2020 13:44:03 +0000
Received: by outflank-mailman (input) for mailman id 42727;
 Wed, 02 Dec 2020 13:44:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQM-0005OF-Tf
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQM-0001uR-Pc
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQM-0007EU-OD
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sUHdS9Q6a1a0WkSKCsg9FfpcgLstsI8+DR53nB5JjPA=; b=Uvx5viWSeIorV9e8XyfZ2kcl7F
	SRa3zPIkaNIjVf4wq5Hs79Bk2Ts8TpbAjt6bzlpHVFZ4tPjZ61KULjAeC+rA8QF8Gm2pcWQEK6H3p
	i/DOYhqgLnFnGFzCxSstFa0LNhFXfMyaCpT+Xzn3uun0NbfeKxLZPYqr7LX/RL4Z3VNc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] evtchn/fifo: use stable fields when recording "last queue" information
Message-Id: <E1kkSQM-0007EU-OD@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 13:44:02 +0000

commit 1fdcfdbfb2b1920a0bbaf8281cb8a7f6e37b2a6f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 1 17:34:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:34:38 2020 +0100

    evtchn/fifo: use stable fields when recording "last queue" information
    
    Both evtchn->priority and evtchn->notify_vcpu_id could change behind the
    back of evtchn_fifo_set_pending(), as for it - in the case of
    interdomain channels - only the remote side's per-channel lock is held.
    Neither the queue's priority nor the vCPU's vcpu_id fields have similar
    properties, so they seem better suited for the purpose. In particular
    they reflect the respective evtchn fields' values at the time they were
    used to determine queue and vCPU.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    master commit: 6f6f07b64cbe90e54f8e62b4d6f2404cf5306536
    master date: 2020-10-02 08:37:35 +0200
---
 xen/common/event_fifo.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 45c024739d..98742ba9cb 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -224,8 +224,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = evtchn->notify_vcpu_id;
-            evtchn->last_priority = evtchn->priority;
+            evtchn->last_vcpu_id = v->vcpu_id;
+            evtchn->last_priority = q->priority;
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 13:44:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 13:44:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42728.76876 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQY-0005P4-MD; Wed, 02 Dec 2020 13:44:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42728.76876; Wed, 02 Dec 2020 13:44:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQY-0005Ox-JE; Wed, 02 Dec 2020 13:44:14 +0000
Received: by outflank-mailman (input) for mailman id 42728;
 Wed, 02 Dec 2020 13:44:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQW-0005Oq-Vx
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQW-0001uU-Uk
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQW-0007Gq-SS
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Fd1Tk4sNvDyoIcynJef9xgLQuhIyhT+FoXl7y6X9B7Y=; b=X9TTx7vD4kPIbrm4c0kZUDCNnw
	k4nzvDmp4chPsA2xb1aR7+Wz6jnfqZ4atVs6EuKY5DWI6GHOYmzOWql7g4XrBz8X4b7a3HhZbtsi+
	7YIgI+ECykkfxoQYJgfqJYqFX0WgJ+S5EXK1XwEXPzjoVCypAvFiLJGDpUvJfg2siMUQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] xen/evtchn: rework per event channel lock
Message-Id: <E1kkSQW-0007Gq-SS@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 13:44:12 +0000

commit f91d2a96b56039c4a6e63b605ac561d68847f515
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:35:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:35:30 2020 +0100

    xen/evtchn: rework per event channel lock
    
    Currently the lock for a single event channel needs to be taken with
    interrupts off, which causes deadlocks in some cases.
    
    Rework the per event channel lock to be non-blocking for the case of
    sending an event and removing the need for disabling interrupts for
    taking the lock.
    
    The lock is needed for avoiding races between event channel state
    changes (creation, closing, binding) against normal operations (set
    pending, [un]masking, priority changes).
    
    Use a rwlock, but with some restrictions:
    
    - Changing the state of an event channel (creation, closing, binding)
      needs to use write_lock(), with ASSERT()ing that the lock is taken as
      writer only when the state of the event channel is either before or
      after the locked region appropriate (either free or unbound).
    
    - Sending an event needs to use read_trylock() mostly, in case of not
      obtaining the lock the operation is omitted. This is needed as
      sending an event can happen with interrupts off (at least in some
      cases).
    
    - Dumping the event channel state for debug purposes is using
      read_trylock(), too, in order to avoid blocking in case the lock is
      taken as writer for a long time.
    
    - All other cases can use read_lock().
    
    Fixes: e045199c7c9c54 ("evtchn: address races with evtchn_reset()")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    
    xen/events: fix build
    
    Commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    introduced a build failure for NDEBUG builds.
    
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    master commit: 5f2df45ead7c1195142f68b7923047a1e9479d54
    master date: 2020-11-10 14:36:15 +0100
    master commit: 53bacb86f496fdb11560d9e3b361bca7de60d268
    master date: 2020-11-11 08:56:21 +0100
---
 xen/arch/x86/irq.c         |   6 +-
 xen/arch/x86/pv/shim.c     |   9 +--
 xen/common/event_channel.c | 141 +++++++++++++++++++++++++++------------------
 xen/include/xen/event.h    |  27 +++++++--
 xen/include/xen/sched.h    |   5 +-
 5 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 01a678b5e2..7b2367e728 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -2330,14 +2330,12 @@ static void dump_irqs(unsigned char key)
                 pirq = domain_irq_to_pirq(d, irq);
                 info = pirq_info(d, pirq);
                 evtchn = evtchn_from_port(d, info->evtchn);
-                local_irq_disable();
-                if ( spin_trylock(&evtchn->lock) )
+                if ( evtchn_read_trylock(evtchn) )
                 {
                     pending = evtchn_is_pending(d, evtchn);
                     masked = evtchn_is_masked(d, evtchn);
-                    spin_unlock(&evtchn->lock);
+                    evtchn_read_unlock(evtchn);
                 }
-                local_irq_enable();
                 printk("%u:%3d(%c%c%c)",
                        d->domain_id, pirq, "-P?"[pending],
                        "-M?"[masked], info->masked ? 'M' : '-');
diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c
index 973b2c31e4..8f01128521 100644
--- a/xen/arch/x86/pv/shim.c
+++ b/xen/arch/x86/pv/shim.c
@@ -603,11 +603,12 @@ void pv_shim_inject_evtchn(unsigned int port)
     if ( port_is_valid(guest, port) )
     {
         struct evtchn *chn = evtchn_from_port(guest, port);
-        unsigned long flags;
 
-        spin_lock_irqsave(&chn->lock, flags);
-        evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
-        spin_unlock_irqrestore(&chn->lock, flags);
+        if ( evtchn_read_trylock(chn) )
+        {
+            evtchn_port_set_pending(guest, chn->notify_vcpu_id, chn);
+            evtchn_read_unlock(chn);
+        }
     }
 }
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 84d58454d2..c20118f104 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -50,6 +50,40 @@
 
 #define consumer_is_xen(e) (!!(e)->xen_consumer)
 
+/*
+ * Lock an event channel exclusively. This is allowed only when the channel is
+ * free or unbound either when taking or when releasing the lock, as any
+ * concurrent operation on the event channel using evtchn_read_trylock() will
+ * just assume the event channel is free or unbound at the moment when the
+ * evtchn_read_trylock() returns false.
+ */
+static inline void evtchn_write_lock(struct evtchn *evtchn)
+{
+    write_lock(&evtchn->lock);
+
+#ifndef NDEBUG
+    evtchn->old_state = evtchn->state;
+#endif
+}
+
+static inline unsigned int old_state(const struct evtchn *evtchn)
+{
+#ifndef NDEBUG
+    return evtchn->old_state;
+#else
+    return ECS_RESERVED; /* Just to allow things to build. */
+#endif
+}
+
+static inline void evtchn_write_unlock(struct evtchn *evtchn)
+{
+    /* Enforce lock discipline. */
+    ASSERT(old_state(evtchn) == ECS_FREE || old_state(evtchn) == ECS_UNBOUND ||
+           evtchn->state == ECS_FREE || evtchn->state == ECS_UNBOUND);
+
+    write_unlock(&evtchn->lock);
+}
+
 /*
  * The function alloc_unbound_xen_event_channel() allows an arbitrary
  * notifier function to be specified. However, very few unique functions
@@ -138,7 +172,7 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
             return NULL;
         }
         chn[i].port = port + i;
-        spin_lock_init(&chn[i].lock);
+        rwlock_init(&chn[i].lock);
     }
     return chn;
 }
@@ -256,7 +290,6 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     int            port;
     domid_t        dom = alloc->dom;
     long           rc;
-    unsigned long  flags;
 
     d = rcu_lock_domain_by_any_id(dom);
     if ( d == NULL )
@@ -272,14 +305,14 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
         chn->u.unbound.remote_domid = current->domain->domain_id;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     alloc->port = port;
 
@@ -292,32 +325,26 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
 }
 
 
-static unsigned long double_evtchn_lock(struct evtchn *lchn,
-                                        struct evtchn *rchn)
+static void double_evtchn_lock(struct evtchn *lchn, struct evtchn *rchn)
 {
-    unsigned long flags;
-
     if ( lchn <= rchn )
     {
-        spin_lock_irqsave(&lchn->lock, flags);
+        evtchn_write_lock(lchn);
         if ( lchn != rchn )
-            spin_lock(&rchn->lock);
+            evtchn_write_lock(rchn);
     }
     else
     {
-        spin_lock_irqsave(&rchn->lock, flags);
-        spin_lock(&lchn->lock);
+        evtchn_write_lock(rchn);
+        evtchn_write_lock(lchn);
     }
-
-    return flags;
 }
 
-static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn,
-                                 unsigned long flags)
+static void double_evtchn_unlock(struct evtchn *lchn, struct evtchn *rchn)
 {
     if ( lchn != rchn )
-        spin_unlock(&lchn->lock);
-    spin_unlock_irqrestore(&rchn->lock, flags);
+        evtchn_write_unlock(lchn);
+    evtchn_write_unlock(rchn);
 }
 
 static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
@@ -327,7 +354,6 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
     long           rc;
-    unsigned long  flags;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -363,7 +389,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     if ( rc )
         goto out;
 
-    flags = double_evtchn_lock(lchn, rchn);
+    double_evtchn_lock(lchn, rchn);
 
     lchn->u.interdomain.remote_dom  = rd;
     lchn->u.interdomain.remote_port = rport;
@@ -380,7 +406,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      */
     evtchn_port_set_pending(ld, lchn->notify_vcpu_id, lchn);
 
-    double_evtchn_unlock(lchn, rchn, flags);
+    double_evtchn_unlock(lchn, rchn);
 
     bind->local_port = lport;
 
@@ -403,7 +429,6 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     struct domain *d = current->domain;
     int            virq = bind->virq, vcpu = bind->vcpu;
     int            rc = 0;
-    unsigned long  flags;
 
     if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
@@ -436,14 +461,14 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_VIRQ;
     chn->notify_vcpu_id = vcpu;
     chn->u.virq         = virq;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     v->virq_to_evtchn[virq] = bind->port = port;
 
@@ -460,7 +485,6 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
-    unsigned long  flags;
 
     if ( (vcpu < 0) || (vcpu >= d->max_vcpus) ||
          (d->vcpu[vcpu] == NULL) )
@@ -473,13 +497,13 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
 
     chn = evtchn_from_port(d, port);
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state          = ECS_IPI;
     chn->notify_vcpu_id = vcpu;
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -523,7 +547,6 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     struct pirq   *info;
     int            port = 0, pirq = bind->pirq;
     long           rc;
-    unsigned long  flags;
 
     if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
@@ -556,14 +579,14 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
     }
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state  = ECS_PIRQ;
     chn->u.pirq.irq = pirq;
     link_pirq_port(port, chn, v);
     evtchn_port_init(d, chn);
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     bind->port = port;
 
@@ -584,7 +607,6 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     struct evtchn *chn1, *chn2;
     int            port2;
     long           rc = 0;
-    unsigned long  flags;
 
  again:
     spin_lock(&d1->event_lock);
@@ -684,14 +706,14 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG_ON(chn2->state != ECS_INTERDOMAIN);
         BUG_ON(chn2->u.interdomain.remote_dom != d1);
 
-        flags = double_evtchn_lock(chn1, chn2);
+        double_evtchn_lock(chn1, chn2);
 
         evtchn_free(d1, chn1);
 
         chn2->state = ECS_UNBOUND;
         chn2->u.unbound.remote_domid = d1->domain_id;
 
-        double_evtchn_unlock(chn1, chn2, flags);
+        double_evtchn_unlock(chn1, chn2);
 
         goto out;
 
@@ -699,9 +721,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
         BUG();
     }
 
-    spin_lock_irqsave(&chn1->lock, flags);
+    evtchn_write_lock(chn1);
     evtchn_free(d1, chn1);
-    spin_unlock_irqrestore(&chn1->lock, flags);
+    evtchn_write_unlock(chn1);
 
  out:
     if ( d2 != NULL )
@@ -721,7 +743,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     struct evtchn *lchn, *rchn;
     struct domain *rd;
     int            rport, ret = 0;
-    unsigned long  flags;
 
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
@@ -734,7 +755,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    evtchn_read_lock(lchn);
 
     /* Guest cannot send via a Xen-attached event channel. */
     if ( unlikely(consumer_is_xen(lchn)) )
@@ -769,7 +790,7 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 
     return ret;
 }
@@ -796,9 +817,11 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     d = v->domain;
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, v->vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, v->vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -827,9 +850,11 @@ static void send_guest_global_virq(struct domain *d, uint32_t virq)
         goto out;
 
     chn = evtchn_from_port(d, port);
-    spin_lock(&chn->lock);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock(&chn->lock);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 
  out:
     spin_unlock_irqrestore(&v->virq_lock, flags);
@@ -839,7 +864,6 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
 {
     int port;
     struct evtchn *chn;
-    unsigned long flags;
 
     /*
      * PV guests: It should not be possible to race with __evtchn_close(). The
@@ -854,9 +878,11 @@ void send_guest_pirq(struct domain *d, const struct pirq *pirq)
     }
 
     chn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&chn->lock, flags);
-    evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
-    spin_unlock_irqrestore(&chn->lock, flags);
+    if ( evtchn_read_trylock(chn) )
+    {
+        evtchn_port_set_pending(d, chn->notify_vcpu_id, chn);
+        evtchn_read_unlock(chn);
+    }
 }
 
 static struct domain *global_virq_handlers[NR_VIRQS] __read_mostly;
@@ -1052,15 +1078,17 @@ int evtchn_unmask(unsigned int port)
 {
     struct domain *d = current->domain;
     struct evtchn *evtchn;
-    unsigned long flags;
 
     if ( unlikely(!port_is_valid(d, port)) )
         return -EINVAL;
 
     evtchn = evtchn_from_port(d, port);
-    spin_lock_irqsave(&evtchn->lock, flags);
+
+    evtchn_read_lock(evtchn);
+
     evtchn_port_unmask(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return 0;
 }
@@ -1306,7 +1334,6 @@ int alloc_unbound_xen_event_channel(
 {
     struct evtchn *chn;
     int            port, rc;
-    unsigned long  flags;
 
     spin_lock(&ld->event_lock);
 
@@ -1319,14 +1346,14 @@ int alloc_unbound_xen_event_channel(
     if ( rc )
         goto out;
 
-    spin_lock_irqsave(&chn->lock, flags);
+    evtchn_write_lock(chn);
 
     chn->state = ECS_UNBOUND;
     chn->xen_consumer = get_xen_consumer(notification_fn);
     chn->notify_vcpu_id = lvcpu;
     chn->u.unbound.remote_domid = remote_domid;
 
-    spin_unlock_irqrestore(&chn->lock, flags);
+    evtchn_write_unlock(chn);
 
     write_atomic(&ld->xen_evtchns, ld->xen_evtchns + 1);
 
@@ -1358,7 +1385,6 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    unsigned long flags;
 
     if ( !port_is_valid(ld, lport) )
     {
@@ -1373,7 +1399,8 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
 
     lchn = evtchn_from_port(ld, lport);
 
-    spin_lock_irqsave(&lchn->lock, flags);
+    if ( !evtchn_read_trylock(lchn) )
+        return;
 
     if ( likely(lchn->state == ECS_INTERDOMAIN) )
     {
@@ -1383,7 +1410,7 @@ void notify_via_xen_event_channel(struct domain *ld, int lport)
         evtchn_port_set_pending(rd, rchn->notify_vcpu_id, rchn);
     }
 
-    spin_unlock_irqrestore(&lchn->lock, flags);
+    evtchn_read_unlock(lchn);
 }
 
 void evtchn_check_pollers(struct domain *d, unsigned int port)
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 87a4aade86..b0c39d402c 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -103,6 +103,21 @@ static inline unsigned int max_evtchns(const struct domain *d)
                           : BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 }
 
+static inline void evtchn_read_lock(struct evtchn *evtchn)
+{
+    read_lock(&evtchn->lock);
+}
+
+static inline bool evtchn_read_trylock(struct evtchn *evtchn)
+{
+    return read_trylock(&evtchn->lock);
+}
+
+static inline void evtchn_read_unlock(struct evtchn *evtchn)
+{
+    read_unlock(&evtchn->lock);
+}
+
 static inline bool_t port_is_valid(struct domain *d, unsigned int p)
 {
     if ( p >= read_atomic(&d->valid_evtchns) )
@@ -236,11 +251,10 @@ static inline bool evtchn_port_is_pending(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
     rc = evtchn_is_pending(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
@@ -255,11 +269,12 @@ static inline bool evtchn_port_is_masked(struct domain *d, evtchn_port_t port)
 {
     struct evtchn *evtchn = evtchn_from_port(d, port);
     bool rc;
-    unsigned long flags;
 
-    spin_lock_irqsave(&evtchn->lock, flags);
+    evtchn_read_lock(evtchn);
+
     rc = evtchn_is_masked(d, evtchn);
-    spin_unlock_irqrestore(&evtchn->lock, flags);
+
+    evtchn_read_unlock(evtchn);
 
     return rc;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 831927fbc4..800b50289d 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -81,7 +81,7 @@ extern domid_t hardware_domid;
 
 struct evtchn
 {
-    spinlock_t lock;
+    rwlock_t lock;
 #define ECS_FREE         0 /* Channel is available for use.                  */
 #define ECS_RESERVED     1 /* Channel is reserved.                           */
 #define ECS_UNBOUND      2 /* Channel is waiting to bind to a remote domain. */
@@ -110,6 +110,9 @@ struct evtchn
         u16 virq;      /* state == ECS_VIRQ */
     } u;
     u8 priority;
+#ifndef NDEBUG
+    u8 old_state;      /* State when taking lock in write mode. */
+#endif
     u8 last_priority;
     u16 last_vcpu_id;
 #ifdef CONFIG_XSM
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 13:44:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 13:44:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42729.76880 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQi-0005Qz-OY; Wed, 02 Dec 2020 13:44:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42729.76880; Wed, 02 Dec 2020 13:44:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQi-0005Qr-Kz; Wed, 02 Dec 2020 13:44:24 +0000
Received: by outflank-mailman (input) for mailman id 42729;
 Wed, 02 Dec 2020 13:44:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQh-0005Qg-4W
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQh-0001uc-37
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQh-0007Hc-1F
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JNBnuJli4+JGEwaeMYAU6KPfnNEs9uJ1wGEb8VuyqJU=; b=mo1bvUsRiYwgL7GTUnUXmFHORi
	R2sXJC3Tjrlc/WvwtheHvFllWaDQwXHj99h1ngC0JOt+a1Jb5zK8hgpks36uJTebNLAw6k698cYmk
	dzhXSqEhlsGj5a1S19LDs08Q/mywOBQvGmiLRZeyswtdsg7imVIqiv/PeeeZKVsfG8wI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] xen/evtchn: revert 52e1fc47abc3a0123
Message-Id: <E1kkSQh-0007Hc-1F@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 13:44:23 +0000

commit f79f47f21c45771ee608b30d2fa5429efb7919e0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:36:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:36:09 2020 +0100

    xen/evtchn: revert 52e1fc47abc3a0123
    
    With the event channel lock no longer disabling interrupts commit
    52e1fc47abc3a0123 ("evtchn/Flask: pre-allocate node on send path") can
    be reverted again.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    master commit: b5ad37f8e9284cc147218f7a5193d739ae7b956f
    master date: 2020-11-10 14:37:15 +0100
---
 xen/common/event_channel.c  |  6 ----
 xen/include/xsm/xsm.h       |  1 -
 xen/xsm/flask/avc.c         | 78 ++++-----------------------------------------
 xen/xsm/flask/hooks.c       | 10 ------
 xen/xsm/flask/include/avc.h |  2 --
 5 files changed, 7 insertions(+), 90 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index c20118f104..3a61a04495 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -747,12 +747,6 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     if ( !port_is_valid(ld, lport) )
         return -EINVAL;
 
-    /*
-     * As the call further down needs to avoid allocations (due to running
-     * with IRQs off), give XSM a chance to pre-allocate if needed.
-     */
-    xsm_evtchn_send(XSM_HOOK, ld, NULL);
-
     lchn = evtchn_from_port(ld, lport);
 
     evtchn_read_lock(lchn);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index d0b4b097c0..2a299f7569 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -59,7 +59,6 @@ struct xsm_operations {
     int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
                                         struct domain *d2, struct evtchn *chn2);
     void (*evtchn_close_post) (struct evtchn *chn);
-    /* Note: Next hook may be called with 'chn' set to NULL. See call site. */
     int (*evtchn_send) (struct domain *d, struct evtchn *chn);
     int (*evtchn_status) (struct domain *d, struct evtchn *chn);
     int (*evtchn_reset) (struct domain *d1, struct domain *d2);
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 8917329225..a3e6108a34 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -24,9 +24,7 @@
 #include <xen/prefetch.h>
 #include <xen/kernel.h>
 #include <xen/sched.h>
-#include <xen/cpu.h>
 #include <xen/init.h>
-#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
@@ -343,79 +341,17 @@ static inline int avc_reclaim_node(void)
     return ecx;
 }
 
-static struct avc_node *new_node(void)
-{
-    struct avc_node *node = xzalloc(struct avc_node);
-
-    if ( node )
-    {
-        INIT_RCU_HEAD(&node->rhead);
-        INIT_HLIST_NODE(&node->list);
-        avc_cache_stats_incr(allocations);
-    }
-
-    return node;
-}
-
-/*
- * avc_has_perm_noaudit() may consume up to two nodes, which we may not be
- * able to obtain from the allocator at that point. Since the is merely
- * about caching earlier decisions, allow for (just) one pre-allocated node.
- */
-static DEFINE_PER_CPU(struct avc_node *, prealloc_node);
-
-void avc_prealloc(void)
-{
-    struct avc_node **prealloc = &this_cpu(prealloc_node);
-
-    if ( !*prealloc )
-        *prealloc = new_node();
-}
-
-static int cpu_callback(struct notifier_block *nfb, unsigned long action,
-                        void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-    struct avc_node **prealloc = &per_cpu(prealloc_node, cpu);
-
-    if ( action == CPU_DEAD && *prealloc )
-    {
-        xfree(*prealloc);
-        *prealloc = NULL;
-        avc_cache_stats_incr(frees);
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-    .priority = 99
-};
-
-static int __init cpu_nfb_init(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(cpu_nfb_init);
-
 static struct avc_node *avc_alloc_node(void)
 {
-    struct avc_node *node, **prealloc = &this_cpu(prealloc_node);
+    struct avc_node *node;
 
-    node = *prealloc;
-    *prealloc = NULL;
+    node = xzalloc(struct avc_node);
+    if (!node)
+        goto out;
 
-    if ( !node )
-    {
-        /* Must not call xmalloc() & Co with IRQs off. */
-        if ( !local_irq_is_enabled() )
-            goto out;
-        node = new_node();
-        if ( !node )
-            goto out;
-    }
+    INIT_RCU_HEAD(&node->rhead);
+    INIT_HLIST_NODE(&node->list);
+    avc_cache_stats_incr(allocations);
 
     atomic_inc(&avc_cache.active_nodes);
     if ( atomic_read(&avc_cache.active_nodes) > avc_cache_threshold )
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 211cfb9a4b..f01b4cfaaa 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -278,16 +278,6 @@ static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
 {
     int rc;
 
-    /*
-     * When called with non-NULL chn, memory allocation may not be permitted.
-     * Allow AVC to preallocate nodes as necessary upon early notification.
-     */
-    if ( !chn )
-    {
-        avc_prealloc();
-        return 0;
-    }
-
     switch ( chn->state )
     {
     case ECS_INTERDOMAIN:
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 8426b36c72..bfc69f4acd 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -90,8 +90,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested,
 int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested,
                                              struct avc_audit_data *auditdata);
 
-void avc_prealloc(void);
-
 /* Exported to selinuxfs */
 struct xen_flask_hash_stats;
 int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 13:44:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 13:44:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42730.76884 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQs-0005Sl-Rz; Wed, 02 Dec 2020 13:44:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42730.76884; Wed, 02 Dec 2020 13:44:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSQs-0005Sd-Ot; Wed, 02 Dec 2020 13:44:34 +0000
Received: by outflank-mailman (input) for mailman id 42730;
 Wed, 02 Dec 2020 13:44:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQr-0005SN-7Q
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQr-0001up-6f
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSQr-0007IP-5e
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=T13S/bDO+oEyPJFrVEifTycrSLK2VkP/Z0Jh3Uzx/lU=; b=x030nNHDwJ0z2oeD+LkMON7F1g
	STKo356SVm/FCqASogosJMXZpHa/crdrFG7Odl9mQxza2m8i8Ct7Ja1RLcaLeLSbe/dS7WbN7lLic
	4CtgqSgNDsfUqj8EaHyYim9S9+s0mm140HsmEZcvbmrYX1o+zlFvPhBQbwuQT9whY4vc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] xen/events: access last_priority and last_vcpu_id together
Message-Id: <E1kkSQr-0007IP-5e@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 13:44:33 +0000

commit 8eb5328e2ec6aa15e371ab64348265b26f00cdf5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:36:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:36:41 2020 +0100

    xen/events: access last_priority and last_vcpu_id together
    
    The queue for a fifo event is depending on the vcpu_id and the
    priority of the event. When sending an event it might happen the
    event needs to change queues and the old queue needs to be kept for
    keeping the links between queue elements intact. For this purpose
    the event channel contains last_priority and last_vcpu_id values
    elements for being able to identify the old queue.
    
    In order to avoid races always access last_priority and last_vcpu_id
    with a single atomic operation avoiding any inconsistencies.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: 1277cb9dc5e966f1faf665bcded02b7533e38078
    master date: 2020-11-24 11:23:42 +0100
---
 xen/common/event_fifo.c | 25 +++++++++++++++++++------
 xen/include/xen/sched.h |  3 +--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 98742ba9cb..b1951a29ad 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -21,6 +21,14 @@
 
 #include <public/event_channel.h>
 
+union evtchn_fifo_lastq {
+    uint32_t raw;
+    struct {
+        uint8_t last_priority;
+        uint16_t last_vcpu_id;
+    };
+};
+
 static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
                                                        unsigned int port)
 {
@@ -64,16 +72,18 @@ static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
     struct vcpu *v;
     struct evtchn_fifo_queue *q, *old_q;
     unsigned int try;
+    union evtchn_fifo_lastq lastq;
 
     for ( try = 0; try < 3; try++ )
     {
-        v = d->vcpu[evtchn->last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        v = d->vcpu[lastq.last_vcpu_id];
+        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         spin_lock_irqsave(&old_q->lock, *flags);
 
-        v = d->vcpu[evtchn->last_vcpu_id];
-        q = &v->evtchn_fifo->queue[evtchn->last_priority];
+        v = d->vcpu[lastq.last_vcpu_id];
+        q = &v->evtchn_fifo->queue[lastq.last_priority];
 
         if ( old_q == q )
             return old_q;
@@ -224,8 +234,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         /* Moved to a different queue? */
         if ( old_q != q )
         {
-            evtchn->last_vcpu_id = v->vcpu_id;
-            evtchn->last_priority = q->priority;
+            union evtchn_fifo_lastq lastq = { };
+
+            lastq.last_vcpu_id = v->vcpu_id;
+            lastq.last_priority = q->priority;
+            write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
             spin_unlock_irqrestore(&old_q->lock, flags);
             spin_lock_irqsave(&q->lock, flags);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 800b50289d..88740cd2ca 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -113,8 +113,7 @@ struct evtchn
 #ifndef NDEBUG
     u8 old_state;      /* State when taking lock in write mode. */
 #endif
-    u8 last_priority;
-    u16 last_vcpu_id;
+    u32 fifo_lastq;    /* Data for fifo events identifying last queue. */
 #ifdef CONFIG_XSM
     union {
 #ifdef XSM_NEED_GENERIC_EVTCHN_SSID
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 13:44:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 13:44:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42731.76888 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSR2-0005UH-TW; Wed, 02 Dec 2020 13:44:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42731.76888; Wed, 02 Dec 2020 13:44:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkSR2-0005U9-QS; Wed, 02 Dec 2020 13:44:44 +0000
Received: by outflank-mailman (input) for mailman id 42731;
 Wed, 02 Dec 2020 13:44:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSR1-0005U0-DO
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSR1-0001uw-CY
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkSR1-0007JF-94
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 13:44:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=TkzHmvlJpxzFliZy+mvEEbf1Un8IcHAHqxLJFJHgoPI=; b=uO7bqO0Mmm5Z8n38DadTmvoCW3
	s75+eXCjCeR5lEURM1Mlq+6KlvagSZ0mDWkzoh/tMpTS2whTAjgr7w8zTmMO5eP3ryPGtAMhMy6nN
	LfpCyLcV3nLrW6Pjw7Vd/eKnXY96XD/Ct5yKuPUWLsHuQQ6JKIXaZRWWI0ZDU9yErEEU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] xen/events: rework fifo queue locking
Message-Id: <E1kkSR1-0007JF-94@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 13:44:43 +0000

commit 1d72d9915edff0dd41f601bbb0b1f83c02ff1689
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 1 17:37:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 1 17:37:21 2020 +0100

    xen/events: rework fifo queue locking
    
    Two cpus entering evtchn_fifo_set_pending() for the same event channel
    can race in case the first one gets interrupted after setting
    EVTCHN_FIFO_PENDING and when the other one manages to set
    EVTCHN_FIFO_LINKED before the first one is testing that bit. This can
    lead to evtchn_check_pollers() being called before the event is put
    properly into the queue, resulting eventually in the guest not seeing
    the event pending and thus blocking forever afterwards.
    
    Note that commit 5f2df45ead7c1195 ("xen/evtchn: rework per event channel
    lock") made the race just more obvious, while the fifo event channel
    implementation had this race forever since the introduction and use of
    per-channel locks, when an unmask operation was running in parallel with
    an event channel send operation.
    
    Using a spinlock for the per event channel lock had turned out
    problematic due to some paths needing to take the lock are called with
    interrupts off, so the lock would need to disable interrupts, which in
    turn broke some use cases related to vm events.
    
    For avoiding this race the queue locking in evtchn_fifo_set_pending()
    needs to be reworked to cover the test of EVTCHN_FIFO_PENDING,
    EVTCHN_FIFO_MASKED and EVTCHN_FIFO_LINKED, too. Additionally when an
    event channel needs to change queues both queues need to be locked
    initially, in order to avoid having a window with no lock held at all.
    
    Reported-by: Jan Beulich <jbeulich@suse.com>
    Fixes: 5f2df45ead7c1195 ("xen/evtchn: rework per event channel lock")
    Fixes: de6acb78bf0e137c ("evtchn: use a per-event channel lock for sending events")
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: 71ac522909e9302350a88bc378be99affa87067c
    master date: 2020-11-30 14:05:39 +0100
---
 xen/common/event_fifo.c | 128 ++++++++++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 58 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index b1951a29ad..0a90a8404d 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -65,38 +65,6 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
                  d->domain_id, evtchn->port);
 }
 
-static struct evtchn_fifo_queue *lock_old_queue(const struct domain *d,
-                                                struct evtchn *evtchn,
-                                                unsigned long *flags)
-{
-    struct vcpu *v;
-    struct evtchn_fifo_queue *q, *old_q;
-    unsigned int try;
-    union evtchn_fifo_lastq lastq;
-
-    for ( try = 0; try < 3; try++ )
-    {
-        lastq.raw = read_atomic(&evtchn->fifo_lastq);
-        v = d->vcpu[lastq.last_vcpu_id];
-        old_q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        spin_lock_irqsave(&old_q->lock, *flags);
-
-        v = d->vcpu[lastq.last_vcpu_id];
-        q = &v->evtchn_fifo->queue[lastq.last_priority];
-
-        if ( old_q == q )
-            return old_q;
-
-        spin_unlock_irqrestore(&old_q->lock, *flags);
-    }
-
-    gprintk(XENLOG_WARNING,
-            "dom%d port %d lost event (too many queue changes)\n",
-            d->domain_id, evtchn->port);
-    return NULL;
-}          
-
 static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
 {
     event_word_t new, old;
@@ -168,6 +136,9 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
     event_word_t *word;
     unsigned long flags;
     bool_t was_pending;
+    struct evtchn_fifo_queue *q, *old_q;
+    unsigned int try;
+    bool linked = true;
 
     port = evtchn->port;
     word = evtchn_fifo_word_from_port(d, port);
@@ -182,17 +153,67 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
+    /*
+     * Lock all queues related to the event channel (in case of a queue change
+     * this might be two).
+     * It is mandatory to do that before setting and testing the PENDING bit
+     * and to hold the current queue lock until the event has been put into the
+     * list of pending events in order to avoid waking up a guest without the
+     * event being visibly pending in the guest.
+     */
+    for ( try = 0; try < 3; try++ )
+    {
+        union evtchn_fifo_lastq lastq;
+        const struct vcpu *old_v;
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+
+        q = &v->evtchn_fifo->queue[evtchn->priority];
+        old_q = &old_v->evtchn_fifo->queue[lastq.last_priority];
+
+        if ( q == old_q )
+            spin_lock_irqsave(&q->lock, flags);
+        else if ( q < old_q )
+        {
+            spin_lock_irqsave(&q->lock, flags);
+            spin_lock(&old_q->lock);
+        }
+        else
+        {
+            spin_lock_irqsave(&old_q->lock, flags);
+            spin_lock(&q->lock);
+        }
+
+        lastq.raw = read_atomic(&evtchn->fifo_lastq);
+        old_v = d->vcpu[lastq.last_vcpu_id];
+        if ( q == &v->evtchn_fifo->queue[evtchn->priority] &&
+             old_q == &old_v->evtchn_fifo->queue[lastq.last_priority] )
+            break;
+
+        if ( q != old_q )
+            spin_unlock(&old_q->lock);
+        spin_unlock_irqrestore(&q->lock, flags);
+    }
+
     was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
+    /* If we didn't get the lock bail out. */
+    if ( try == 3 )
+    {
+        gprintk(XENLOG_WARNING,
+                "%pd port %u lost event (too many queue changes)\n",
+                d, evtchn->port);
+        goto done;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
          !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
-        bool_t linked = 0;
 
         /*
          * Control block not mapped.  The guest must not unmask an
@@ -203,25 +224,11 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         {
             printk(XENLOG_G_WARNING
                    "%pv has no FIFO event channel control block\n", v);
-            goto done;
+            goto unlock;
         }
 
-        /*
-         * No locking around getting the queue. This may race with
-         * changing the priority but we are allowed to signal the
-         * event once on the old priority.
-         */
-        q = &v->evtchn_fifo->queue[evtchn->priority];
-
-        old_q = lock_old_queue(d, evtchn, &flags);
-        if ( !old_q )
-            goto done;
-
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-        {
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            goto done;
-        }
+            goto unlock;
 
         /*
          * If this event was a tail, the old queue is now empty and
@@ -240,8 +247,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             lastq.last_priority = q->priority;
             write_atomic(&evtchn->fifo_lastq, lastq.raw);
 
-            spin_unlock_irqrestore(&old_q->lock, flags);
-            spin_lock_irqsave(&q->lock, flags);
+            spin_unlock(&old_q->lock);
+            old_q = q;
         }
 
         /*
@@ -254,6 +261,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
          * If the queue is empty (i.e., we haven't linked to the new
          * event), head must be updated.
          */
+        linked = false;
         if ( q->tail )
         {
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
@@ -262,15 +270,19 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !linked )
             write_atomic(q->head, port);
         q->tail = port;
+    }
 
-        spin_unlock_irqrestore(&q->lock, flags);
+ unlock:
+    if ( q != old_q )
+        spin_unlock(&old_q->lock);
+    spin_unlock_irqrestore(&q->lock, flags);
 
-        if ( !linked
-             && !guest_test_and_set_bit(d, q->priority,
-                                        &v->evtchn_fifo->control_block->ready) )
-            vcpu_mark_events_pending(v);
-    }
  done:
+    if ( !linked &&
+         !guest_test_and_set_bit(d, q->priority,
+                                 &v->evtchn_fifo->control_block->ready) )
+        vcpu_mark_events_pending(v);
+
     if ( !was_pending )
         evtchn_check_pollers(d, port);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 02 18:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 02 Dec 2020 18:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.42949.77287 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkWao-0000jZ-VM; Wed, 02 Dec 2020 18:11:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 42949.77287; Wed, 02 Dec 2020 18:11:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkWao-0000jR-S1; Wed, 02 Dec 2020 18:11:06 +0000
Received: by outflank-mailman (input) for mailman id 42949;
 Wed, 02 Dec 2020 18:11:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkWan-0000jM-RC
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 18:11:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkWan-0008Gl-Il
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 18:11:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkWan-0006uL-E1
 for xen-changelog@lists.xenproject.org; Wed, 02 Dec 2020 18:11:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7fNz1VNrX5KGSNCzaH7VSMBNXI7Qd81tUIfCM47u41U=; b=KxfuronvXrOZsumosr42VTjTXr
	OxThMWsNdHEFfDcy+AMI76sWiKTBx1iuni/6XvPj6lQxrOK8lWDbEofkJG6XSco0bahxcdkPIYqKP
	k3+nRWkZSFoaMg9XTYFRY9HA1G8PcDBSWYgPannP/rxRVqORoSvnTCzjR5xCV7vH45b8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/iommu: vtd: Fix undefined behavior pci_vtd_quirks()
Message-Id: <E1kkWan-0006uL-E1@xenbits.xenproject.org>
Date: Wed, 02 Dec 2020 18:11:05 +0000

commit aec46884784c2494a30221da775d4ac2c43a4d42
Author:     Julien Grall <jgrall@amazon.com>
AuthorDate: Tue Nov 17 13:45:47 2020 +0000
Commit:     Julien Grall <jgrall@amazon.com>
CommitDate: Wed Dec 2 18:02:11 2020 +0000

    xen/iommu: vtd: Fix undefined behavior pci_vtd_quirks()
    
    When booting Xen with CONFIG_USBAN=y on Sandy Bridge, UBSAN will throw
    the following splat:
    
    (XEN) ================================================================================
    (XEN) UBSAN: Undefined behaviour in quirks.c:449:63
    (XEN) left shift of 1 by 31 places cannot be represented in type 'int'
    (XEN) ----[ Xen-4.11.4  x86_64  debug=y   Not tainted ]----
    
    [...]
    
    (XEN) Xen call trace:
    (XEN)    [<ffff82d0802c0ccc>] ubsan.c#ubsan_epilogue+0xa/0xad
    (XEN)    [<ffff82d0802c16c9>] __ubsan_handle_shift_out_of_bounds+0xb4/0x145
    (XEN)    [<ffff82d0802eeecd>] pci_vtd_quirk+0x3d3/0x74f
    (XEN)    [<ffff82d0802e508b>] iommu.c#domain_context_mapping+0x45b/0x46f
    (XEN)    [<ffff82d08053f39e>] iommu.c#setup_hwdom_device+0x22/0x3a
    (XEN)    [<ffff82d08053dfbc>] pci.c#setup_one_hwdom_device+0x8c/0x124
    (XEN)    [<ffff82d08053e302>] pci.c#_setup_hwdom_pci_devices+0xbb/0x2f7
    (XEN)    [<ffff82d0802da5b7>] pci.c#pci_segments_iterate+0x4c/0x8c
    (XEN)    [<ffff82d08053e8bd>] setup_hwdom_pci_devices+0x25/0x2c
    (XEN)    [<ffff82d08053e916>] iommu.c#intel_iommu_hwdom_init+0x52/0x2f3
    (XEN)    [<ffff82d08053d6da>] iommu_hwdom_init+0x4e/0xa4
    (XEN)    [<ffff82d080577f32>] dom0_construct_pv+0x23c8/0x2476
    (XEN)    [<ffff82d08057cb50>] construct_dom0+0x6c/0xa3
    (XEN)    [<ffff82d080564822>] __start_xen+0x4651/0x4b55
    (XEN)    [<ffff82d0802000f3>] __high_start+0x53/0x55
    
    Note that splat is from 4.11.4 and not staging. Although, the problem is
    still present.
    
    This can be solved by making the first operand unsigned int.
    
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
 xen/drivers/passthrough/vtd/quirks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index a8330f17bc..8a81d9c930 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -435,7 +435,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x3728: /* Xeon C5500/C3500 (JasperForest) */
     case 0x3c28: /* Sandybridge */
         val = pci_conf_read32(pdev->sbdf, 0x1AC);
-        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
+        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1U << 31));
         printk(XENLOG_INFO "Masked VT-d error signaling on %pp\n", &pdev->sbdf);
         break;
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 03 16:00:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 03 Dec 2020 16:00:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.43820.78692 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1X-0006NH-7p; Thu, 03 Dec 2020 16:00:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 43820.78692; Thu, 03 Dec 2020 16:00:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1X-0006Mg-4I; Thu, 03 Dec 2020 16:00:03 +0000
Received: by outflank-mailman (input) for mailman id 43820;
 Thu, 03 Dec 2020 16:00:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1W-00063T-Cq
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1W-0000Qt-AM
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1W-0008CB-8R
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=NGvzBALNMXxw+Ltw6cJHh69B0uAQyMJKhnDoKh8D/9I=; b=pfwx10/hpW3mLBBLBm4thWkpQM
	I/4FNTctlxYumVdsH3ci0NYtGzWvCArWmaOffdrX5ehrL0Ij3iCSvBDaXPXAzNjQAxzIl7lNeFo60
	7Nd7EG/ZJBd/BYkvgwgxStBfIOfIZTrVYrV03qJxwJ9gdUWcRZluU3BexIQFxgD5aGOY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] ns16550: gate all PCI code with CONFIG_X86
Message-Id: <E1kkr1W-0008CB-8R@xenbits.xenproject.org>
Date: Thu, 03 Dec 2020 16:00:02 +0000

commit b00d0576723fa2155c0c8f5345a40335e0bc3912
Author:     Rahul Singh <rahul.singh@arm.com>
AuthorDate: Wed Dec 2 10:09:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:09:27 2020 +0100

    ns16550: gate all PCI code with CONFIG_X86
    
    The NS16550 driver is assuming that NS16550 PCI card are usable if the
    architecture supports PCI (i.e. CONFIG_HAS_PCI=y). However, the code is
    very x86 focus and will fail to build on Arm (/!\ it is not all the
    errors):
    
    ns16550.c: In function ‘ns16550_init_irq’:
    ns16550.c:726:21: error: implicit declaration of function ‘create_irq’;
    did you mean ‘release_irq’? [-Werror=implicit-function-declaration]
              uart->irq = create_irq(0, false);
                          ^~~~~~~~~~
                          release_irq
    ns16550.c:726:21: error: nested extern declaration of ‘create_irq’
    [-Werror=nested-externs]
    ns16550.c: In function ‘ns16550_init_postirq’:
    ns16550.c:768:33: error: ‘mmio_ro_ranges’ undeclared (first use in this
    function); did you mean ‘mmio_handler’?
                   rangeset_add_range(mmio_ro_ranges, uart->io_base,
                                      ^~~~~~~~~~~~~~
                                      mmio_handler
    ns16550.c:768:33: note: each undeclared identifier is reported only once
    for each function it appears in
    ns16550.c:780:20: error: variable ‘msi’ has initializer but incomplete
    type
                  struct msi_info msi = {
                         ^~~~~~~~
    
    Enabling support for NS16550 PCI card on Arm would require more plumbing
    in addition to fixing the compilation error.
    
    Arm systems tend to have platform UART available such as NS16550, PL011.
    So there are limited reasons to get NS16550 PCI support for now on Arm.
    
    Guard all remaining PCI code that is not under x86 flag with CONFIG_X86.
    
    No functional change intended.
    
    Signed-off-by: Rahul Singh <rahul.singh@arm.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Stefano Stabellini <sstabellini@kernel.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/drivers/char/ns16550.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 9235d854fe..16a73d0c0e 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -8,6 +8,15 @@
  * Copyright (c) 2003-2005, K A Fraser
  */
 
+/*
+ * The PCI part of the code in this file currently is only known to
+ * work on x86. Undo this hack once the logic has been suitably
+ * abstracted.
+ */
+#if defined(CONFIG_HAS_PCI) && defined(CONFIG_X86)
+# define NS16550_PCI
+#endif
+
 #include <xen/console.h>
 #include <xen/init.h>
 #include <xen/irq.h>
@@ -16,7 +25,7 @@
 #include <xen/timer.h>
 #include <xen/serial.h>
 #include <xen/iocap.h>
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 #include <xen/pci_ids.h>
@@ -51,7 +60,7 @@ static struct ns16550 {
     unsigned int timeout_ms;
     bool_t intr_works;
     bool_t dw_usr_bsy;
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     /* PCI card parameters. */
     bool_t pb_bdf_enable;   /* if =1, pb-bdf effective, port behind bridge */
     bool_t ps_bdf_enable;   /* if =1, ps_bdf effective, port on pci card */
@@ -66,7 +75,7 @@ static struct ns16550 {
 #endif
 } ns16550_com[2] = { { 0 } };
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
 struct ns16550_config {
     u16 vendor_id;
     u16 dev_id;
@@ -256,7 +265,7 @@ static int ns16550_getc(struct serial_port *port, char *pc)
 
 static void pci_serial_early_init(struct ns16550 *uart)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
         return;
 
@@ -355,7 +364,7 @@ static void __init ns16550_init_preirq(struct serial_port *port)
 
 static void __init ns16550_init_irq(struct serial_port *port)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     struct ns16550 *uart = port->uart;
 
     if ( uart->msi )
@@ -397,7 +406,7 @@ static void __init ns16550_init_postirq(struct serial_port *port)
     uart->timeout_ms = max_t(
         unsigned int, 1, (bits * uart->fifo_size * 1000) / uart->baud);
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( uart->bar || uart->ps_bdf_enable )
     {
         if ( uart->param && uart->param->mmio &&
@@ -477,7 +486,7 @@ static void ns16550_suspend(struct serial_port *port)
 
     stop_timer(&uart->timer);
 
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     if ( uart->bar )
        uart->cr = pci_conf_read16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1],
                                   uart->ps_bdf[2]), PCI_COMMAND);
@@ -486,7 +495,7 @@ static void ns16550_suspend(struct serial_port *port)
 
 static void _ns16550_resume(struct serial_port *port)
 {
-#ifdef CONFIG_HAS_PCI
+#ifdef NS16550_PCI
     struct ns16550 *uart = port->uart;
 
     if ( uart->bar )
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 03 16:00:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 03 Dec 2020 16:00:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.43822.78695 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1h-0006yo-9J; Thu, 03 Dec 2020 16:00:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 43822.78695; Thu, 03 Dec 2020 16:00:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1h-0006yg-5y; Thu, 03 Dec 2020 16:00:13 +0000
Received: by outflank-mailman (input) for mailman id 43822;
 Thu, 03 Dec 2020 16:00:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1g-0006yZ-Fp
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1g-0000bI-F0
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1g-0008EE-DI
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yYWOd+XEEZ6MDRd76oqjfQn0jf0QvOT4yRtPxaJOePA=; b=CzsrgUvjyMFyqvomaycdsnqkge
	y4Sfzq5YDLF3JPdo6rk6bcAKjPPovqHXOeD79YGke0ezy5oQxWKKqQBQrPpPOY6hFofYCVrQ7ts+B
	6tU4EJdgpQHJjEn4qBTlR/kr3mGWLU+RP+gRhGoU29V+TR7FG1+RfEq4OkqWcfoJfiZQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: add cpu to sched_res_mask when removing it from cpupool
Message-Id: <E1kkr1g-0008EE-DI@xenbits.xenproject.org>
Date: Thu, 03 Dec 2020 16:00:12 +0000

commit 9f5ce6e5953456d499e05b48db1de5724d4b09de
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:12:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:12:04 2020 +0100

    xen/cpupool: add cpu to sched_res_mask when removing it from cpupool
    
    When a cpu is removed from a cpupool and added to the free cpus it
    should be added to sched_res_mask, too.
    
    The related removal from sched_res_mask in case of core scheduling
    is already done in schedule_cpu_add().
    
    As long as all cpupools share the same scheduling granularity there
    is nothing going wrong with the missing addition, but this will change
    when per-cpupool granularity is fully supported.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index ed973e90ec..f8c81592af 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -3189,6 +3189,7 @@ int schedule_cpu_rm(unsigned int cpu)
             /* Adjust cpu masks of resources (old and new). */
             cpumask_clear_cpu(cpu_iter, sr->cpus);
             cpumask_set_cpu(cpu_iter, sr_new[idx]->cpus);
+            cpumask_set_cpu(cpu_iter, &sched_res_mask);
 
             /* Init timer. */
             init_timer(&sr_new[idx]->s_timer, s_timer_fn, NULL, cpu_iter);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 03 16:00:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 03 Dec 2020 16:00:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.43825.78714 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1r-00076v-Oe; Thu, 03 Dec 2020 16:00:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 43825.78714; Thu, 03 Dec 2020 16:00:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr1r-00076m-Kd; Thu, 03 Dec 2020 16:00:23 +0000
Received: by outflank-mailman (input) for mailman id 43825;
 Thu, 03 Dec 2020 16:00:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1q-00075A-Kg
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1q-0000bV-JR
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr1q-0008F6-HX
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nEekqW6cddm8gbksnUDmwacGuDnJcr0k/89KesRm7EE=; b=L/Sjxfdmsnp0WEHZAhpZZ+b2Ye
	gIDlNIT8pPYouoS0+0hYyOfUzBrIbdtIepSCXI+yL1FKcmE7LfvY4DGBXujtgXHZV7rk2rMJR0aKL
	kkxK65aU4n/c4lLT4yns72Pvd3YtwRqnyJ3E6qrftZBsfev6rF5MNEHUJWNYlRF59bL0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: add missing bits for per-cpupool scheduling granularity
Message-Id: <E1kkr1q-0008F6-HX@xenbits.xenproject.org>
Date: Thu, 03 Dec 2020 16:00:22 +0000

commit 1283ad87c6314daed6e9e7af2ab5202d96276202
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:12:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:12:37 2020 +0100

    xen/cpupool: add missing bits for per-cpupool scheduling granularity
    
    Even with storing the scheduling granularity in struct cpupool there
    are still a few bits missing for being able to have cpupools with
    different granularity (apart from the missing interface for setting
    the individual granularities): the number of cpus in a scheduling
    unit is always taken from the global sched_granularity variable.
    
    So store the value in struct cpupool and use that instead of
    sched_granularity.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 3 ++-
 xen/common/sched/private.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 7ea641ca26..6429c8f7b5 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -151,7 +151,7 @@ static void __init cpupool_gran_init(void)
 
 unsigned int cpupool_get_granularity(const struct cpupool *c)
 {
-    return c ? sched_granularity : 1;
+    return c ? c->sched_gran : 1;
 }
 
 static void free_cpupool_struct(struct cpupool *c)
@@ -289,6 +289,7 @@ static struct cpupool *cpupool_create(
     }
     c->sched->cpupool = c;
     c->gran = opt_sched_granularity;
+    c->sched_gran = sched_granularity;
 
     *q = c;
 
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index df50976eb2..685992cab9 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -514,6 +514,7 @@ struct cpupool
     struct scheduler *sched;
     atomic_t         refcnt;
     enum sched_gran  gran;
+    unsigned int     sched_gran;     /* Number of cpus per sched-item. */
 };
 
 static inline cpumask_t *cpupool_domain_master_cpumask(const struct domain *d)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 03 16:00:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 03 Dec 2020 16:00:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.43828.78718 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr22-0007FK-QC; Thu, 03 Dec 2020 16:00:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 43828.78718; Thu, 03 Dec 2020 16:00:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr22-0007FC-M9; Thu, 03 Dec 2020 16:00:34 +0000
Received: by outflank-mailman (input) for mailman id 43828;
 Thu, 03 Dec 2020 16:00:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr20-0007Ef-PJ
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr20-0000cL-OJ
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr20-0008Fs-Lw
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JCtzDBC1UNDPMZRY9HgbobkKX6GBhtMyn4VE/x+uLYw=; b=FYBakKVkpbFMjT/r24dXARsmfv
	ci1sEGZUNhT/U8BFe0J6Wk1G7DoKnyWXqkZ32uRKrdWQ4oYlwwhNamf4ql5BoauBKcFxkLRS0IubP
	5I2ECPaP88svbdsIChEiyyK0DOPyOHPVR9ZlZIxVMjJN8GgD27lcIkAAHeXIzlu4C0q0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: sort included headers in cpupool.c
Message-Id: <E1kkr20-0008Fs-Lw@xenbits.xenproject.org>
Date: Thu, 03 Dec 2020 16:00:32 +0000

commit b2a88b2e09611f0050ab33767cb878a83171c4bc
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:13:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:13:09 2020 +0100

    xen/cpupool: sort included headers in cpupool.c
    
    Common style is to include header files in alphabetical order. Sort the
    #include statements in cpupool.c accordingly.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 6429c8f7b5..84f326ea63 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -11,15 +11,15 @@
  * (C) 2009, Juergen Gross, Fujitsu Technology Solutions
  */
 
-#include <xen/lib.h>
-#include <xen/init.h>
+#include <xen/cpu.h>
 #include <xen/cpumask.h>
+#include <xen/init.h>
+#include <xen/keyhandler.h>
+#include <xen/lib.h>
 #include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
 #include <xen/warning.h>
-#include <xen/keyhandler.h>
-#include <xen/cpu.h>
 
 #include "private.h"
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 03 16:00:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 03 Dec 2020 16:00:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.43831.78722 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr2C-0007HZ-Qn; Thu, 03 Dec 2020 16:00:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 43831.78722; Thu, 03 Dec 2020 16:00:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkr2C-0007HR-Ns; Thu, 03 Dec 2020 16:00:44 +0000
Received: by outflank-mailman (input) for mailman id 43831;
 Thu, 03 Dec 2020 16:00:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr2A-0007H7-UF
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr2A-0000cW-SS
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkr2A-0008Ga-Qk
 for xen-changelog@lists.xenproject.org; Thu, 03 Dec 2020 16:00:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=v0q2fDFlklhkTuqrsOVgRll9BWOF+HMWSgDPjdnohXk=; b=TW5aLiFMBdfhyHhTtq+YyJmIyf
	CEx/T+p8M4CLsZqkA+ksNdvlDc+UoPU+/7PTjmI+bhlzJDMlDCilYxk/gxoZW6r8S8SVVtOXc0d+T
	XV/crlTf3MJ+PwVBpTqJVVcWfY0l69cAE3Jz906JQVH840gsyZyaKsj636OSUwmOugkA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs: fix hypfs path documentation
Message-Id: <E1kkr2A-0008Ga-Qk@xenbits.xenproject.org>
Date: Thu, 03 Dec 2020 16:00:42 +0000

commit cabf60fc32d4cfa1d74a2bdfcdb294a31da5d68e
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Dec 2 10:13:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 2 10:13:52 2020 +0100

    docs: fix hypfs path documentation
    
    The /params/* entry is missing a writable tag.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/hypfs-paths.pandoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc
index dddb592bc5..6c7b2f7ee3 100644
--- a/docs/misc/hypfs-paths.pandoc
+++ b/docs/misc/hypfs-paths.pandoc
@@ -179,7 +179,7 @@ The minor version of Xen.
 
 A directory of runtime parameters.
 
-#### /params/*
+#### /params/* [w]
 
 The individual parameters. The description of the different parameters can be
 found in `docs/misc/xen-command-line.pandoc`.
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 00:33:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 00:33:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44022.78966 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkz1z-0000b4-IN; Fri, 04 Dec 2020 00:33:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44022.78966; Fri, 04 Dec 2020 00:33:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kkz1z-0000av-FN; Fri, 04 Dec 2020 00:33:03 +0000
Received: by outflank-mailman (input) for mailman id 44022;
 Fri, 04 Dec 2020 00:33:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkz1y-0000aq-I7
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 00:33:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkz1y-00042g-Fi
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 00:33:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kkz1y-0005nU-EX
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 00:33:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QExBcpYnRPRAyMBj5ldl//nJskQuarOoPF7BWu/idHk=; b=4hu9tZReAjiJFjGcUFmsjgR22j
	V+2lad2sv6NBwWVvuSIb1F2KafcNCd0wuNcjY819JVRz9C9LZG6bMUC4MoU4FwKlb4/vDAPa6EH00
	780aL4WzLC7VO6E28MlP9r9Ita9SaduQ+4/9NegFmb3Lgc7EdGgfwxG5SBzEr0SKb2ns=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/iommu: vtd: Fix undefined behavior pci_vtd_quirks()
Message-Id: <E1kkz1y-0005nU-EX@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 00:33:02 +0000

commit aec46884784c2494a30221da775d4ac2c43a4d42
Author:     Julien Grall <jgrall@amazon.com>
AuthorDate: Tue Nov 17 13:45:47 2020 +0000
Commit:     Julien Grall <jgrall@amazon.com>
CommitDate: Wed Dec 2 18:02:11 2020 +0000

    xen/iommu: vtd: Fix undefined behavior pci_vtd_quirks()
    
    When booting Xen with CONFIG_USBAN=y on Sandy Bridge, UBSAN will throw
    the following splat:
    
    (XEN) ================================================================================
    (XEN) UBSAN: Undefined behaviour in quirks.c:449:63
    (XEN) left shift of 1 by 31 places cannot be represented in type 'int'
    (XEN) ----[ Xen-4.11.4  x86_64  debug=y   Not tainted ]----
    
    [...]
    
    (XEN) Xen call trace:
    (XEN)    [<ffff82d0802c0ccc>] ubsan.c#ubsan_epilogue+0xa/0xad
    (XEN)    [<ffff82d0802c16c9>] __ubsan_handle_shift_out_of_bounds+0xb4/0x145
    (XEN)    [<ffff82d0802eeecd>] pci_vtd_quirk+0x3d3/0x74f
    (XEN)    [<ffff82d0802e508b>] iommu.c#domain_context_mapping+0x45b/0x46f
    (XEN)    [<ffff82d08053f39e>] iommu.c#setup_hwdom_device+0x22/0x3a
    (XEN)    [<ffff82d08053dfbc>] pci.c#setup_one_hwdom_device+0x8c/0x124
    (XEN)    [<ffff82d08053e302>] pci.c#_setup_hwdom_pci_devices+0xbb/0x2f7
    (XEN)    [<ffff82d0802da5b7>] pci.c#pci_segments_iterate+0x4c/0x8c
    (XEN)    [<ffff82d08053e8bd>] setup_hwdom_pci_devices+0x25/0x2c
    (XEN)    [<ffff82d08053e916>] iommu.c#intel_iommu_hwdom_init+0x52/0x2f3
    (XEN)    [<ffff82d08053d6da>] iommu_hwdom_init+0x4e/0xa4
    (XEN)    [<ffff82d080577f32>] dom0_construct_pv+0x23c8/0x2476
    (XEN)    [<ffff82d08057cb50>] construct_dom0+0x6c/0xa3
    (XEN)    [<ffff82d080564822>] __start_xen+0x4651/0x4b55
    (XEN)    [<ffff82d0802000f3>] __high_start+0x53/0x55
    
    Note that splat is from 4.11.4 and not staging. Although, the problem is
    still present.
    
    This can be solved by making the first operand unsigned int.
    
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
 xen/drivers/passthrough/vtd/quirks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index a8330f17bc..8a81d9c930 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -435,7 +435,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x3728: /* Xeon C5500/C3500 (JasperForest) */
     case 0x3c28: /* Sandybridge */
         val = pci_conf_read32(pdev->sbdf, 0x1AC);
-        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
+        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1U << 31));
         printk(XENLOG_INFO "Masked VT-d error signaling on %pp\n", &pdev->sbdf);
         break;
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 07:33:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 07:33:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44076.79020 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5aV-0005Bk-OB; Fri, 04 Dec 2020 07:33:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44076.79020; Fri, 04 Dec 2020 07:33:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5aV-0005Ba-Jq; Fri, 04 Dec 2020 07:33:07 +0000
Received: by outflank-mailman (input) for mailman id 44076;
 Fri, 04 Dec 2020 07:33:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5aU-0005BV-1R
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5aT-0001ao-US
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5aT-0002n8-SR
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Y/nmgvZXX4sUqZqLxNVPDWaVGPqa5yMTuwb5/mnKPSg=; b=AZFmw1AIs5YUJFoUzxGjnMKL9G
	vpxnqOjmSOB1SjKAArd0PR3ANtydFfKvutHcvABFs3jegX13pMWW26yOO+PKH21os1lhiRWeSFYEa
	CQ4teR4h1lE90V4w2tAz0UI+9keAueM9a9rXf+zY2rTphJ+3rZWxFSaiudSMtkkmdaxA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] evtchn: avoid access tearing for ->virq_to_evtchn[] accesses
Message-Id: <E1kl5aT-0002n8-SR@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 07:33:05 +0000

commit 8be06d7055dc73823e2dacd6da14620d6ef4beed
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 08:27:26 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:27:26 2020 +0100

    evtchn: avoid access tearing for ->virq_to_evtchn[] accesses
    
    Use {read,write}_atomic() to exclude any eventualities, in particular
    observing that accesses aren't all happening under a consistent lock.
    
    Requested-by: Julien Grall <julien@xen.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_channel.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index dbfba62a49..59f95f2eb2 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -441,7 +441,7 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     spin_lock(&d->event_lock);
 
-    if ( v->virq_to_evtchn[virq] != 0 )
+    if ( read_atomic(&v->virq_to_evtchn[virq]) )
         ERROR_EXIT(-EEXIST);
 
     if ( port != 0 )
@@ -469,7 +469,8 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     evtchn_write_unlock(chn);
 
-    v->virq_to_evtchn[virq] = bind->port = port;
+    bind->port = port;
+    write_atomic(&v->virq_to_evtchn[virq], port);
 
  out:
     spin_unlock(&d->event_lock);
@@ -655,9 +656,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     case ECS_VIRQ:
         for_each_vcpu ( d1, v )
         {
-            if ( v->virq_to_evtchn[chn1->u.virq] != port1 )
+            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) != port1 )
                 continue;
-            v->virq_to_evtchn[chn1->u.virq] = 0;
+            write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
             spin_barrier(&v->virq_lock);
         }
         break;
@@ -796,7 +797,7 @@ bool evtchn_virq_enabled(const struct vcpu *v, unsigned int virq)
     if ( virq_is_global(virq) && v->vcpu_id )
         v = domain_vcpu(v->domain, 0);
 
-    return v->virq_to_evtchn[virq];
+    return read_atomic(&v->virq_to_evtchn[virq]);
 }
 
 void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
@@ -810,7 +811,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     spin_lock_irqsave(&v->virq_lock, flags);
 
-    port = v->virq_to_evtchn[virq];
+    port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
         goto out;
 
@@ -844,7 +845,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
 
     spin_lock_irqsave(&v->virq_lock, flags);
 
-    port = v->virq_to_evtchn[virq];
+    port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
         goto out;
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 07:33:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 07:33:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44077.79022 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5af-0005EB-RV; Fri, 04 Dec 2020 07:33:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44077.79022; Fri, 04 Dec 2020 07:33:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5af-0005E4-OI; Fri, 04 Dec 2020 07:33:17 +0000
Received: by outflank-mailman (input) for mailman id 44077;
 Fri, 04 Dec 2020 07:33:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ae-0005Dm-57
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ae-0001ay-3p
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ae-0002nk-2m
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=skUqjxzG5pIlZVDjxVKRYU0vuFu50+oRkunvbGwKupI=; b=K40TplnZVcpZTkxy7MDrvF0Y3z
	n4FuA2sTiiF0wZp8x8KrNzdYXtBdss9EeLKczGLt8+GY/XbflBffr7BUxgiMKsaIOPUwVFV9UG1WU
	2r+DkJr622MMzubwuoQ7gJiD0Iur1BoCDTVzTHmQ9TmLiS65Za0Rdu3xo7y+5JYfqqU0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] fix spelling errors
Message-Id: <E1kl5ae-0002nk-2m@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 07:33:16 +0000

commit ba6e78f0db820fbeea4df41fde4655020ca05928
Author:     Diederik de Haas <didi.debian@cknow.org>
AuthorDate: Fri Dec 4 08:28:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:28:21 2020 +0100

    fix spelling errors
    
    Only spelling errors; no functional changes.
    
    In docs/misc/dump-core-format.txt there are a few more instances of
    'informations'. I'll leave that up to someone who can properly determine
    how those sentences should be constructed.
    
    Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
    Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 docs/man/xl.1.pod.in                   | 2 +-
 docs/man/xl.cfg.5.pod.in               | 2 +-
 docs/man/xlcpupool.cfg.5.pod           | 2 +-
 tools/firmware/rombios/rombios.c       | 2 +-
 tools/libs/light/libxl_stream_read.c   | 2 +-
 tools/xl/xl_cmdtable.c                 | 2 +-
 xen/arch/x86/boot/video.S              | 2 +-
 xen/arch/x86/cpu/vpmu.c                | 2 +-
 xen/arch/x86/mpparse.c                 | 2 +-
 xen/arch/x86/x86_emulate/x86_emulate.c | 2 +-
 xen/common/libelf/libelf-dominfo.c     | 2 +-
 xen/drivers/passthrough/arm/smmu.c     | 2 +-
 xen/tools/gen-cpuid.py                 | 2 +-
 xen/xsm/flask/policy/access_vectors    | 2 +-
 14 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index f92bacfa72..eaa72faad6 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1578,7 +1578,7 @@ List vsnd devices for a domain.
 Creates a new keyboard device in the domain specified by I<domain-id>.
 I<vkb-device> describes the device to attach, using the same format as the
 B<VKB_SPEC_STRING> string in the domain config file. See L<xl.cfg(5)>
-for more informations.
+for more information.
 
 =item B<vkb-detach> I<domain-id> I<devid>
 
diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 0532739c1f..b4625f56db 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -2385,7 +2385,7 @@ If B<videoram> is set less than 128MB, an error will be triggered.
 
 =item B<stdvga=BOOLEAN>
 
-Speficies a standard VGA card with VBE (VESA BIOS Extensions) as the
+Specifies a standard VGA card with VBE (VESA BIOS Extensions) as the
 emulated graphics device. If your guest supports VBE 2.0 or
 later (e.g. Windows XP onwards) then you should enable this.
 stdvga supports more video ram and bigger resolutions than Cirrus.
diff --git a/docs/man/xlcpupool.cfg.5.pod b/docs/man/xlcpupool.cfg.5.pod
index 3c9ddf7958..c577c7ca3a 100644
--- a/docs/man/xlcpupool.cfg.5.pod
+++ b/docs/man/xlcpupool.cfg.5.pod
@@ -106,7 +106,7 @@ means that cpus 2,3,5 will be member of the cpupool.
 means that cpus 0,2,3 and 5 will be member of the cpupool. A "node:" or
 "nodes:" modifier can be used. E.g., "0,node:1,nodes:2-3,^10-13" means
 that pcpus 0, plus all the cpus of NUMA nodes 1,2,3 with the exception
-of cpus 10,11,12,13 will be memeber of the cpupool.
+of cpus 10,11,12,13 will be members of the cpupool.
 
 =back
 
diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c
index 51558ee57a..5cda22785f 100644
--- a/tools/firmware/rombios/rombios.c
+++ b/tools/firmware/rombios/rombios.c
@@ -2607,7 +2607,7 @@ void ata_detect( )
   write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11);
 #endif
 #if BX_MAX_ATA_INTERFACES > 4
-#error Please fill the ATA interface informations
+#error Please fill the ATA interface information
 #endif
 
   // Device detection
diff --git a/tools/libs/light/libxl_stream_read.c b/tools/libs/light/libxl_stream_read.c
index 514f6d9f89..99a6714e76 100644
--- a/tools/libs/light/libxl_stream_read.c
+++ b/tools/libs/light/libxl_stream_read.c
@@ -459,7 +459,7 @@ static void stream_continue(libxl__egc *egc,
         while (process_record(egc, stream))
             ; /*
                * Nothing! process_record() helpfully tells us if no specific
-               * futher actions have been set up, in which case we want to go
+               * further actions have been set up, in which case we want to go
                * ahead and process the next record.
                */
         break;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 7da6c1b927..6ab5e47da3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -154,7 +154,7 @@ struct cmd_spec cmd_table[] = {
       "-h  Print this help.\n"
       "-c  Leave domain running after creating the snapshot.\n"
       "-p  Leave domain paused after creating the snapshot.\n"
-      "-D  Store the domain id in the configration."
+      "-D  Store the domain id in the configuration."
     },
     { "migrate",
       &main_migrate, 0, 1,
diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S
index a485779ce7..0efbe8d3b3 100644
--- a/xen/arch/x86/boot/video.S
+++ b/xen/arch/x86/boot/video.S
@@ -177,7 +177,7 @@ dac_set:
         movb    $0, _param(PARAM_LFB_COLORS+7)
 
 dac_done:
-# get protected mode interface informations
+# get protected mode interface information
         movw    $0x4f0a, %ax
         xorw    %bx, %bx
         xorw    %di, %di
diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 1ed39ef03f..ab667361d3 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -680,7 +680,7 @@ static void pvpmu_finish(struct domain *d, xen_pmu_params_t *params)
         vcpu_unpause(v);
 }
 
-/* Dump some vpmu informations on console. Used in keyhandler dump_domains(). */
+/* Dump some vpmu information to console. Used in keyhandler dump_domains(). */
 void vpmu_dump(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index d532575fee..dff02b142b 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -170,7 +170,7 @@ static int MP_processor_info_x(struct mpc_config_processor *m,
 	if (num_processors >= 8 && hotplug
 	    && genapic.name == apic_default.name) {
 		printk_once(XENLOG_WARNING
-			    "WARNING: CPUs limit of 8 reached - ignoring futher processors\n");
+			    "WARNING: CPUs limit of 8 reached - ignoring further processors\n");
 		unaccounted_cpus = true;
 		return -ENOSPC;
 	}
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index a35b63634b..6ac0787745 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3246,7 +3246,7 @@ x86_decode(
             case 0x23: /* mov reg,dr */
                 /*
                  * Mov to/from cr/dr ignore the encoding of Mod, and behave as
-                 * if they were encoded as reg/reg instructions.  No futher
+                 * if they were encoded as reg/reg instructions.  No further
                  * disp/SIB bytes are fetched.
                  */
                 modrm_mod = 3;
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
index 508f08db42..69c94b6f3b 100644
--- a/xen/common/libelf/libelf-dominfo.c
+++ b/xen/common/libelf/libelf-dominfo.c
@@ -1,5 +1,5 @@
 /*
- * parse xen-specific informations out of elf kernel binaries.
+ * parse xen-specific information out of elf kernel binaries.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index b8321f5d8d..ed04d85e05 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -214,7 +214,7 @@ struct iommu_domain
 	struct list_head		list;
 };
 
-/* Xen: Describes informations required for a Xen domain */
+/* Xen: Describes information required for a Xen domain */
 struct arm_smmu_xen_domain {
 	spinlock_t			lock;
 	/* List of context (i.e iommu_domain) associated to this domain */
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 50412b9a46..36f67750e5 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -192,7 +192,7 @@ def crunch_numbers(state):
         FXSR: [FFXSR, SSE],
 
         # SSE is taken to mean support for the %XMM registers as well as the
-        # instructions.  Several futher instruction sets are built on core
+        # instructions.  Several further instruction sets are built on core
         # %XMM support, without specific inter-dependencies.  Additionally
         # AMD has a special mis-alignment sub-mode.
         SSE: [SSE2, MISALIGNSSE],
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 1aa0bb501c..6359c7fc87 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -507,7 +507,7 @@ class security
 #
 class version
 {
-# Extra informations (-unstable).
+# Extra information (-unstable).
     xen_extraversion
 # Compile information of the hypervisor.
     xen_compile_info
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 07:33:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 07:33:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44078.79026 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5ap-0005GH-TN; Fri, 04 Dec 2020 07:33:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44078.79026; Fri, 04 Dec 2020 07:33:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5ap-0005G9-QB; Fri, 04 Dec 2020 07:33:27 +0000
Received: by outflank-mailman (input) for mailman id 44078;
 Fri, 04 Dec 2020 07:33:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ao-0005Ft-9m
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ao-0001b9-7h
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ao-0002oI-6g
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=k5dFpRBqHlsOIBriaQUrDtOMiv8cVsh3lbVxfV+PhPw=; b=WB3xRZRVb3OZv3ewG8Um8Q0Egd
	d+vZpIsV0WmJiuJM1iyJDZ30D0Pzf7eXXpUpvv5NftffKKTXHeLMd9oq6Mn+DRm8CRpeCJpWBu36m
	83dbx5Q4TR4YXlnIwxSga2teyH0v5sc0JFAYZDk4TtfY4IEJ8VDlB9YlIoAc4AFe+Sms=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/hypfs: move per-node function pointers into a dedicated struct
Message-Id: <E1kl5ao-0002oI-6g@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 07:33:26 +0000

commit d29033719b8246d7bbef9b0fff2b6a168b7d1b56
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:29:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:29:41 2020 +0100

    xen/hypfs: move per-node function pointers into a dedicated struct
    
    Move the function pointers currently stored in each hypfs node into a
    dedicated structure in order to save some space for each node. This
    will save even more space with additional callbacks added in future.
    
    Provide some standard function vectors.
    
    Instead of testing the write pointer to be not NULL provide a dummy
    function just returning -EACCESS. ASSERT() all vector entries being
    populated when adding a node. This avoids any potential problem (e.g.
    pv domain privilege escalations) in case of calling a non populated
    vector entry.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c      | 41 +++++++++++++++++++++++-----
 xen/include/xen/hypfs.h | 71 ++++++++++++++++++++++++++++++++++---------------
 xen/include/xen/param.h | 15 ++++-------
 3 files changed, 88 insertions(+), 39 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 8e932b5cf9..7befd144ba 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -24,6 +24,27 @@ CHECK_hypfs_dirlistentry;
     (DIRENTRY_NAME_OFF +        \
      ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
 
+const struct hypfs_funcs hypfs_dir_funcs = {
+    .read = hypfs_read_dir,
+    .write = hypfs_write_deny,
+};
+const struct hypfs_funcs hypfs_leaf_ro_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_deny,
+};
+const struct hypfs_funcs hypfs_leaf_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_leaf,
+};
+const struct hypfs_funcs hypfs_bool_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_bool,
+};
+const struct hypfs_funcs hypfs_custom_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_custom,
+};
+
 static DEFINE_RWLOCK(hypfs_lock);
 enum hypfs_lock_state {
     hypfs_unlocked,
@@ -74,6 +95,9 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
     int ret = -ENOENT;
     struct hypfs_entry *e;
 
+    ASSERT(new->funcs->read);
+    ASSERT(new->funcs->write);
+
     hypfs_write_lock();
 
     list_for_each_entry ( e, &parent->dirlist, list )
@@ -284,7 +308,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
 
     guest_handle_add_offset(uaddr, sizeof(e));
 
-    ret = entry->read(entry, uaddr);
+    ret = entry->funcs->read(entry, uaddr);
 
  out:
     return ret;
@@ -297,6 +321,7 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
     int ret;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
+    ASSERT(leaf->e.max_size);
 
     if ( ulen > leaf->e.max_size )
         return -ENOSPC;
@@ -357,6 +382,7 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
     int ret;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
+    ASSERT(leaf->e.max_size);
 
     /* Avoid oversized buffer allocation. */
     if ( ulen > MAX_PARAM_SIZE )
@@ -382,19 +408,20 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
     return ret;
 }
 
+int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
+                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+{
+    return -EACCES;
+}
+
 static int hypfs_write(struct hypfs_entry *entry,
                        XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
 {
     struct hypfs_entry_leaf *l;
 
-    if ( !entry->write )
-        return -EACCES;
-
-    ASSERT(entry->max_size);
-
     l = container_of(entry, struct hypfs_entry_leaf, e);
 
-    return entry->write(l, uaddr, ulen);
+    return entry->funcs->write(l, uaddr, ulen);
 }
 
 long do_hypfs_op(unsigned int cmd,
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 5ad99cb558..25fdf3ead7 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -7,6 +7,32 @@
 #include <public/hypfs.h>
 
 struct hypfs_entry_leaf;
+struct hypfs_entry;
+
+/*
+ * Per-node callbacks:
+ *
+ * The callbacks are always called with the hypfs lock held.
+ *
+ * The read() callback is used to return the contents of a node (either
+ * directory or leaf). It is NOT used to get directory entries during traversal
+ * of the tree.
+ *
+ * The write() callback is used to modify the contents of a node. Writing
+ * directories is not supported (this means all nodes are added at boot time).
+ */
+struct hypfs_funcs {
+    int (*read)(const struct hypfs_entry *entry,
+                XEN_GUEST_HANDLE_PARAM(void) uaddr);
+    int (*write)(struct hypfs_entry_leaf *leaf,
+                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+};
+
+extern const struct hypfs_funcs hypfs_dir_funcs;
+extern const struct hypfs_funcs hypfs_leaf_ro_funcs;
+extern const struct hypfs_funcs hypfs_leaf_wr_funcs;
+extern const struct hypfs_funcs hypfs_bool_wr_funcs;
+extern const struct hypfs_funcs hypfs_custom_wr_funcs;
 
 struct hypfs_entry {
     unsigned short type;
@@ -15,10 +41,7 @@ struct hypfs_entry {
     unsigned int max_size;
     const char *name;
     struct list_head list;
-    int (*read)(const struct hypfs_entry *entry,
-                XEN_GUEST_HANDLE_PARAM(void) uaddr);
-    int (*write)(struct hypfs_entry_leaf *leaf,
-                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+    const struct hypfs_funcs *funcs;
 };
 
 struct hypfs_entry_leaf {
@@ -42,7 +65,7 @@ struct hypfs_entry_dir {
         .e.size = 0,                              \
         .e.max_size = 0,                          \
         .e.list = LIST_HEAD_INIT(var.e.list),     \
-        .e.read = hypfs_read_dir,                 \
+        .e.funcs = &hypfs_dir_funcs,              \
         .dirlist = LIST_HEAD_INIT(var.dirlist),   \
     }
 
@@ -52,7 +75,7 @@ struct hypfs_entry_dir {
         .e.encoding = XEN_HYPFS_ENC_PLAIN,        \
         .e.name = (nam),                          \
         .e.max_size = (msz),                      \
-        .e.read = hypfs_read_leaf,                \
+        .e.funcs = &hypfs_leaf_ro_funcs,          \
     }
 
 /* Content and size need to be set via hypfs_string_set_reference(). */
@@ -72,35 +95,37 @@ static inline void hypfs_string_set_reference(struct hypfs_entry_leaf *leaf,
     leaf->e.size = strlen(str) + 1;
 }
 
-#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, wr) \
-    struct hypfs_entry_leaf __read_mostly var = {        \
-        .e.type = (typ),                                 \
-        .e.encoding = XEN_HYPFS_ENC_PLAIN,               \
-        .e.name = (nam),                                 \
-        .e.size = sizeof(contvar),                       \
-        .e.max_size = (wr) ? sizeof(contvar) : 0,        \
-        .e.read = hypfs_read_leaf,                       \
-        .e.write = (wr),                                 \
-        .u.content = &(contvar),                         \
+#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, fn, wr) \
+    struct hypfs_entry_leaf __read_mostly var = {            \
+        .e.type = (typ),                                     \
+        .e.encoding = XEN_HYPFS_ENC_PLAIN,                   \
+        .e.name = (nam),                                     \
+        .e.size = sizeof(contvar),                           \
+        .e.max_size = (wr) ? sizeof(contvar) : 0,            \
+        .e.funcs = (fn),                                     \
+        .u.content = &(contvar),                             \
     }
 
 #define HYPFS_UINT_INIT(var, nam, contvar)                       \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_UINT_INIT_WRITABLE(var, nam, contvar)              \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
-                         hypfs_write_leaf)
+                         &hypfs_leaf_wr_funcs, 1)
 
 #define HYPFS_INT_INIT(var, nam, contvar)                        \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar,  \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_INT_INIT_WRITABLE(var, nam, contvar)               \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, \
-                         hypfs_write_leaf)
+                         &hypfs_leaf_wr_funcs, 1)
 
 #define HYPFS_BOOL_INIT(var, nam, contvar)                       \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_BOOL_INIT_WRITABLE(var, nam, contvar)              \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
-                         hypfs_write_bool)
+                         &hypfs_bool_wr_funcs, 1)
 
 extern struct hypfs_entry_dir hypfs_root;
 
@@ -112,6 +137,8 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr);
+int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
+                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
diff --git a/xen/include/xen/param.h b/xen/include/xen/param.h
index d0409d3a0e..1b2c7db954 100644
--- a/xen/include/xen/param.h
+++ b/xen/include/xen/param.h
@@ -116,8 +116,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
         { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
           .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
           .hypfs.e.name = (nam), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_custom, \
+          .hypfs.e.funcs = &hypfs_custom_wr_funcs, \
           .init_leaf = (initfunc), \
           .func = (variable) }
 #define boolean_runtime_only_param(nam, variable) \
@@ -127,8 +126,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_bool, \
+          .hypfs.e.funcs = &hypfs_bool_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define integer_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -137,8 +135,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define size_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -147,8 +144,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define string_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -157,8 +153,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = 0, \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 
 #else
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 07:33:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 07:33:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44079.79030 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5az-0005HU-Ux; Fri, 04 Dec 2020 07:33:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44079.79030; Fri, 04 Dec 2020 07:33:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5az-0005HM-Rp; Fri, 04 Dec 2020 07:33:37 +0000
Received: by outflank-mailman (input) for mailman id 44079;
 Fri, 04 Dec 2020 07:33:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ay-0005HE-Bp
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ay-0001bK-B4
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5ay-0002oz-A7
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=01zjW9P/nrLjyZAmt/2ZQcFoY9Gas5babJoii06QT0k=; b=0OSCuRO4IMeIUyRZNEoYydpBxR
	faJDOorJvQQ5P3HlyFud5GYvLvO2IHhtjskEmTLBGWzEKleQ3KmctkH5z+pH4RYZ+KdufFhGmA4gW
	sYcEE6K4hsO47+u6nt7UrHHlIugWsr5DrpXEkzPYJwJPBL5YpFisfEdGpSP8airA0GWw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/hypfs: pass real failure reason up from hypfs_get_entry()
Message-Id: <E1kl5ay-0002oz-A7@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 07:33:36 +0000

commit f1b920bb06c6fb3bdad8a483fb6ecf5c76069799
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:30:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:30:17 2020 +0100

    xen/hypfs: pass real failure reason up from hypfs_get_entry()
    
    Instead of handling all errors from hypfs_get_entry() as ENOENT pass
    up the real error value via ERR_PTR().
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 7befd144ba..fdfd0f764a 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -187,7 +187,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
     while ( again )
     {
         if ( dir->e.type != XEN_HYPFS_TYPE_DIR )
-            return NULL;
+            return ERR_PTR(-ENOENT);
 
         if ( !*path )
             return &dir->e;
@@ -206,7 +206,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
                                                      struct hypfs_entry_dir, e);
 
             if ( cmp < 0 )
-                return NULL;
+                return ERR_PTR(-ENOENT);
             if ( !cmp && strlen(entry->name) == name_len )
             {
                 if ( !*end )
@@ -221,13 +221,13 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
         }
     }
 
-    return NULL;
+    return ERR_PTR(-ENOENT);
 }
 
 static struct hypfs_entry *hypfs_get_entry(const char *path)
 {
     if ( path[0] != '/' )
-        return NULL;
+        return ERR_PTR(-EINVAL);
 
     return hypfs_get_entry_rel(&hypfs_root, path + 1);
 }
@@ -454,9 +454,9 @@ long do_hypfs_op(unsigned int cmd,
         goto out;
 
     entry = hypfs_get_entry(path);
-    if ( !entry )
+    if ( IS_ERR(entry) )
     {
-        ret = -ENOENT;
+        ret = PTR_ERR(entry);
         goto out;
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 07:33:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 07:33:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44080.79034 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5bA-0005Ip-1G; Fri, 04 Dec 2020 07:33:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44080.79034; Fri, 04 Dec 2020 07:33:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl5b9-0005Ih-TU; Fri, 04 Dec 2020 07:33:47 +0000
Received: by outflank-mailman (input) for mailman id 44080;
 Fri, 04 Dec 2020 07:33:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5b8-0005IV-Fa
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5b8-0001bz-Ef
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl5b8-0002pw-Dh
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 07:33:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fa4wGoNcpLT/29Rv3vgQ6firBC9QvusWfAXMyeoXaNo=; b=Mguu/Ar6t/FCdBEd/JCagUSMkX
	Jc4zjK1uR2gQVozjKov4wZhhmde5XODcHba4JMxXCnV93phV7uJu4uVRc8OHs1WUP9HltJWXYp64O
	WpdDImblOAd8JwfSiDpi+UQtLXdCRxDzvAhSIzGcNRmN+QkybJ09zM6u1otmoUr3fwys=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/hypfs: add getsize() and findentry() callbacks to hypfs_funcs
Message-Id: <E1kl5b8-0002pw-Dh@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 07:33:46 +0000

commit be3755af37263833cb3b1c6b1f2ba219bdf97ec3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:31:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:31:25 2020 +0100

    xen/hypfs: add getsize() and findentry() callbacks to hypfs_funcs
    
    Add a getsize() function pointer to struct hypfs_funcs for being able
    to have dynamically filled entries without the need to take the hypfs
    lock each time the contents are being generated.
    
    For directories add a findentry callback to the vector and modify
    hypfs_get_entry_rel() to use it. For its non-directory node counterpart
    introduce the so far unused and hence missing ENOTDIR error code.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c         | 100 +++++++++++++++++++++++++++++----------------
 xen/include/public/errno.h |   1 +
 xen/include/xen/hypfs.h    |  25 +++++++++++-
 3 files changed, 90 insertions(+), 36 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index fdfd0f764a..2e8e90591e 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -27,22 +27,32 @@ CHECK_hypfs_dirlistentry;
 const struct hypfs_funcs hypfs_dir_funcs = {
     .read = hypfs_read_dir,
     .write = hypfs_write_deny,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_dir_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_ro_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_deny,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_leaf,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_bool_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_bool,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_custom_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_custom,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 
 static DEFINE_RWLOCK(hypfs_lock);
@@ -97,6 +107,8 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
 
     ASSERT(new->funcs->read);
     ASSERT(new->funcs->write);
+    ASSERT(new->funcs->getsize);
+    ASSERT(new->funcs->findentry);
 
     hypfs_write_lock();
 
@@ -176,15 +188,41 @@ static int hypfs_get_path_user(char *buf,
     return 0;
 }
 
+struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
+                                         const char *name,
+                                         unsigned int name_len)
+{
+    return ERR_PTR(-ENOTDIR);
+}
+
+struct hypfs_entry *hypfs_dir_findentry(const struct hypfs_entry_dir *dir,
+                                        const char *name,
+                                        unsigned int name_len)
+{
+    struct hypfs_entry *entry;
+
+    list_for_each_entry ( entry, &dir->dirlist, list )
+    {
+        int cmp = strncmp(name, entry->name, name_len);
+
+        if ( cmp < 0 )
+            return ERR_PTR(-ENOENT);
+
+        if ( !cmp && strlen(entry->name) == name_len )
+            return entry;
+    }
+
+    return ERR_PTR(-ENOENT);
+}
+
 static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
                                                const char *path)
 {
     const char *end;
     struct hypfs_entry *entry;
     unsigned int name_len;
-    bool again = true;
 
-    while ( again )
+    for ( ; ; )
     {
         if ( dir->e.type != XEN_HYPFS_TYPE_DIR )
             return ERR_PTR(-ENOENT);
@@ -197,28 +235,12 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
             end = strchr(path, '\0');
         name_len = end - path;
 
-        again = false;
+        entry = dir->e.funcs->findentry(dir, path, name_len);
+        if ( IS_ERR(entry) || !*end )
+            return entry;
 
-        list_for_each_entry ( entry, &dir->dirlist, list )
-        {
-            int cmp = strncmp(path, entry->name, name_len);
-            struct hypfs_entry_dir *d = container_of(entry,
-                                                     struct hypfs_entry_dir, e);
-
-            if ( cmp < 0 )
-                return ERR_PTR(-ENOENT);
-            if ( !cmp && strlen(entry->name) == name_len )
-            {
-                if ( !*end )
-                    return entry;
-
-                again = true;
-                dir = d;
-                path = end + 1;
-
-                break;
-            }
-        }
+        path = end + 1;
+        dir = container_of(entry, struct hypfs_entry_dir, e);
     }
 
     return ERR_PTR(-ENOENT);
@@ -232,12 +254,17 @@ static struct hypfs_entry *hypfs_get_entry(const char *path)
     return hypfs_get_entry_rel(&hypfs_root, path + 1);
 }
 
+unsigned int hypfs_getsize(const struct hypfs_entry *entry)
+{
+    return entry->size;
+}
+
 int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr)
 {
     const struct hypfs_entry_dir *d;
     const struct hypfs_entry *e;
-    unsigned int size = entry->size;
+    unsigned int size = entry->funcs->getsize(entry);
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
@@ -252,7 +279,7 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
         direntry.e.pad = 0;
         direntry.e.type = e->type;
         direntry.e.encoding = e->encoding;
-        direntry.e.content_len = e->size;
+        direntry.e.content_len = e->funcs->getsize(e);
         direntry.e.max_write_len = e->max_size;
         direntry.off_next = list_is_last(&e->list, &d->dirlist) ? 0 : e_len;
         if ( copy_to_guest(uaddr, &direntry, 1) )
@@ -275,18 +302,20 @@ int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr)
 {
     const struct hypfs_entry_leaf *l;
+    unsigned int size = entry->funcs->getsize(entry);
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
     l = container_of(entry, const struct hypfs_entry_leaf, e);
 
-    return copy_to_guest(uaddr, l->u.content, entry->size) ? -EFAULT: 0;
+    return copy_to_guest(uaddr, l->u.content, size) ?  -EFAULT : 0;
 }
 
 static int hypfs_read(const struct hypfs_entry *entry,
                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
 {
     struct xen_hypfs_direntry e;
+    unsigned int size = entry->funcs->getsize(entry);
     long ret = -EINVAL;
 
     if ( ulen < sizeof(e) )
@@ -295,7 +324,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
     e.pad = 0;
     e.type = entry->type;
     e.encoding = entry->encoding;
-    e.content_len = entry->size;
+    e.content_len = size;
     e.max_write_len = entry->max_size;
 
     ret = -EFAULT;
@@ -303,7 +332,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
         goto out;
 
     ret = -ENOBUFS;
-    if ( ulen < entry->size + sizeof(e) )
+    if ( ulen < size + sizeof(e) )
         goto out;
 
     guest_handle_add_offset(uaddr, sizeof(e));
@@ -319,15 +348,16 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
 {
     char *buf;
     int ret;
+    struct hypfs_entry *e = &leaf->e;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
     ASSERT(leaf->e.max_size);
 
-    if ( ulen > leaf->e.max_size )
+    if ( ulen > e->max_size )
         return -ENOSPC;
 
-    if ( leaf->e.type != XEN_HYPFS_TYPE_STRING &&
-         leaf->e.type != XEN_HYPFS_TYPE_BLOB && ulen != leaf->e.size )
+    if ( e->type != XEN_HYPFS_TYPE_STRING &&
+         e->type != XEN_HYPFS_TYPE_BLOB && ulen != e->funcs->getsize(e) )
         return -EDOM;
 
     buf = xmalloc_array(char, ulen);
@@ -339,14 +369,14 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
         goto out;
 
     ret = -EINVAL;
-    if ( leaf->e.type == XEN_HYPFS_TYPE_STRING &&
-         leaf->e.encoding == XEN_HYPFS_ENC_PLAIN &&
+    if ( e->type == XEN_HYPFS_TYPE_STRING &&
+         e->encoding == XEN_HYPFS_ENC_PLAIN &&
          memchr(buf, 0, ulen) != (buf + ulen - 1) )
         goto out;
 
     ret = 0;
     memcpy(leaf->u.write_ptr, buf, ulen);
-    leaf->e.size = ulen;
+    e->size = ulen;
 
  out:
     xfree(buf);
@@ -360,7 +390,7 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
     ASSERT(leaf->e.type == XEN_HYPFS_TYPE_BOOL &&
-           leaf->e.size == sizeof(bool) &&
+           leaf->e.funcs->getsize(&leaf->e) == sizeof(bool) &&
            leaf->e.max_size == sizeof(bool) );
 
     if ( ulen != leaf->e.max_size )
diff --git a/xen/include/public/errno.h b/xen/include/public/errno.h
index e1d02fcddf..5c53af6af9 100644
--- a/xen/include/public/errno.h
+++ b/xen/include/public/errno.h
@@ -78,6 +78,7 @@ XEN_ERRNO(EBUSY,	16)	/* Device or resource busy */
 XEN_ERRNO(EEXIST,	17)	/* File exists */
 XEN_ERRNO(EXDEV,	18)	/* Cross-device link */
 XEN_ERRNO(ENODEV,	19)	/* No such device */
+XEN_ERRNO(ENOTDIR,	20)	/* Not a directory */
 XEN_ERRNO(EISDIR,	21)	/* Is a directory */
 XEN_ERRNO(EINVAL,	22)	/* Invalid argument */
 XEN_ERRNO(ENFILE,	23)	/* File table overflow */
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 25fdf3ead7..53f50772b4 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -2,17 +2,21 @@
 #define __XEN_HYPFS_H__
 
 #ifdef CONFIG_HYPFS
+#include <xen/lib.h>
 #include <xen/list.h>
 #include <xen/string.h>
 #include <public/hypfs.h>
 
 struct hypfs_entry_leaf;
+struct hypfs_entry_dir;
 struct hypfs_entry;
 
 /*
  * Per-node callbacks:
  *
- * The callbacks are always called with the hypfs lock held.
+ * The callbacks are always called with the hypfs lock held. In case multiple
+ * callbacks are called for a single operation the lock is held across all
+ * those callbacks.
  *
  * The read() callback is used to return the contents of a node (either
  * directory or leaf). It is NOT used to get directory entries during traversal
@@ -20,12 +24,24 @@ struct hypfs_entry;
  *
  * The write() callback is used to modify the contents of a node. Writing
  * directories is not supported (this means all nodes are added at boot time).
+ *
+ * getsize() is called in two cases:
+ * - when reading a node (directory or leaf) for filling in the size of the
+ *   node into the returned direntry
+ * - when reading a directory for each node in this directory
+ *
+ * findentry() is called for traversing a path from the root node to a node
+ * for all nodes on that path excluding the final node (so for looking up
+ * "/a/b/c" findentry() will be called for "/", "/a", and "/a/b").
  */
 struct hypfs_funcs {
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
                  XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+    unsigned int (*getsize)(const struct hypfs_entry *entry);
+    struct hypfs_entry *(*findentry)(const struct hypfs_entry_dir *dir,
+                                     const char *name, unsigned int name_len);
 };
 
 extern const struct hypfs_funcs hypfs_dir_funcs;
@@ -145,6 +161,13 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
                        XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+unsigned int hypfs_getsize(const struct hypfs_entry *entry);
+struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
+                                         const char *name,
+                                         unsigned int name_len);
+struct hypfs_entry *hypfs_dir_findentry(const struct hypfs_entry_dir *dir,
+                                        const char *name,
+                                        unsigned int name_len);
 #endif
 
 #endif /* __XEN_HYPFS_H__ */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 11:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 11:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44666.80046 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl9g1-0007l9-S9; Fri, 04 Dec 2020 11:55:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44666.80046; Fri, 04 Dec 2020 11:55:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kl9g1-0007l1-P2; Fri, 04 Dec 2020 11:55:05 +0000
Received: by outflank-mailman (input) for mailman id 44666;
 Fri, 04 Dec 2020 11:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl9g1-0007kv-AK
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 11:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl9g1-0000Uu-7y
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 11:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kl9g1-0005YA-6c
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 11:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GXpDq41AnmrfWU//zQI/dS5kEAVVo5f8YGBYDyvmYqI=; b=fvpzWlhwP85Kr0UA66th+G7ed+
	5YKS3Vqzy2kjdFJQmarlhHTF+JZjIMlt5GidOWfOVHtZ4VwdPnGWpwaitC3PYZU1zYnX9r9f/0b8Z
	apFJUfwyT+iO7WALlooaqkN2CkuyvIYOynwfKzWy5qXrkIkokynHfF5MPd7Z53GdTRao=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/hotplug: allow tuning of xenwatchdogd arguments
Message-Id: <E1kl9g1-0005YA-6c@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 11:55:05 +0000

commit 0fb6dbfaa859aae0e51a82a8d5e213bcc64b85f1
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Thu Dec 3 07:34:36 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Fri Dec 4 11:51:14 2020 +0000

    tools/hotplug: allow tuning of xenwatchdogd arguments
    
    Currently the arguments for xenwatchdogd are hardcoded with 15s
    keep-alive interval and 30s timeout.
    
    It is not possible to tweak these values via
    /etc/systemd/system/xen-watchdog.service.d/*.conf because ExecStart
    can not be replaced. The only option would be a private copy
    /etc/systemd/system/xen-watchdog.service, which may get out of sync
    with the Xen provided xen-watchdog.service.
    
    Adjust the service file to recognize XENWATCHDOGD_ARGS= in a
    private unit configuration file.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/hotplug/Linux/init.d/xen-watchdog.in          | 7 ++++++-
 tools/hotplug/Linux/systemd/xen-watchdog.service.in | 4 +++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/hotplug/Linux/init.d/xen-watchdog.in b/tools/hotplug/Linux/init.d/xen-watchdog.in
index c05f1f6b6a..a0bde199c4 100644
--- a/tools/hotplug/Linux/init.d/xen-watchdog.in
+++ b/tools/hotplug/Linux/init.d/xen-watchdog.in
@@ -19,6 +19,11 @@
 
 . @XEN_SCRIPT_DIR@/hotplugpath.sh
 
+xencommons_config=@CONFIG_DIR@/@CONFIG_LEAF_DIR@
+
+test -f $xencommons_config/xencommons && . $xencommons_config/xencommons
+
+test -n "$XENWATCHDOGD_ARGS" || XENWATCHDOGD_ARGS='30 15'
 DAEMON=${sbindir}/xenwatchdogd
 base=$(basename $DAEMON)
 
@@ -46,7 +51,7 @@ start() {
 	local r
 	echo -n $"Starting domain watchdog daemon: "
 
-	$DAEMON 30 15
+	$DAEMON $XENWATCHDOGD_ARGS
 	r=$?
 	[ "$r" -eq 0 ] && success $"$base startup" || failure $"$base startup"
 	echo
diff --git a/tools/hotplug/Linux/systemd/xen-watchdog.service.in b/tools/hotplug/Linux/systemd/xen-watchdog.service.in
index 1eecd2a616..637ab7fd7f 100644
--- a/tools/hotplug/Linux/systemd/xen-watchdog.service.in
+++ b/tools/hotplug/Linux/systemd/xen-watchdog.service.in
@@ -6,7 +6,9 @@ ConditionPathExists=/proc/xen/capabilities
 
 [Service]
 Type=forking
-ExecStart=@sbindir@/xenwatchdogd 30 15
+Environment="XENWATCHDOGD_ARGS=30 15"
+EnvironmentFile=-@CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons
+ExecStart=@sbindir@/xenwatchdogd $XENWATCHDOGD_ARGS
 KillSignal=USR1
 
 [Install]
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44709.80110 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6B-0002uA-HF; Fri, 04 Dec 2020 12:22:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44709.80110; Fri, 04 Dec 2020 12:22:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6B-0002u2-EE; Fri, 04 Dec 2020 12:22:07 +0000
Received: by outflank-mailman (input) for mailman id 44709;
 Fri, 04 Dec 2020 12:22:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA69-0002tx-Ie
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA69-0001EI-FB
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA69-0007qG-Dj
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OU6C+/prJ55RVfZT34G7CYCkgg0up7WN4Y3jLUq08NY=; b=g6DdfnOWYWY1Su/q17x6CT+Nob
	3mviX5IrZsZI2WW1PfFQHWVDGgwQcunuYLP0dc4M08oNmoDO/ND2lb5/IKiJsP+yrAL1F7Hc+rdUq
	11lt50d1pCOFyL26PuqxA9t6+z0LRXfl2/pEzCxgv2EYEZZiwoegwnw8Ub87aCIJBvmE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: don't blindly write to 32-bit registers if 'mode' is invalid
Message-Id: <E1klA69-0007qG-Dj@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:05 +0000

commit 7c8946dae39b544094d969ef902d49e8ea0ea973
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:12:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:12:54 2020 +0100

    viridian: don't blindly write to 32-bit registers if 'mode' is invalid
    
    If hvm_guest_x86_mode() returns something other than 8 or 4 then
    viridian_hypercall() will return immediately but, on the way out, will write
    back status as if 'mode' was 4. This patch simply makes it leave the registers
    alone.
    
    NOTE: The formatting of the 'out' label and the switch statement are also
          adjusted as per CODING_STYLE.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index dc7183a546..3dbb5c2d4c 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -692,13 +692,15 @@ int viridian_hypercall(struct cpu_user_regs *regs)
         break;
     }
 
-out:
+ out:
     output.result = status;
-    switch (mode) {
+    switch ( mode )
+    {
     case 8:
         regs->rax = output.raw;
         break;
-    default:
+
+    case 4:
         regs->rdx = output.raw >> 32;
         regs->rax = (uint32_t)output.raw;
         break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44710.80114 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6L-0002vH-Iw; Fri, 04 Dec 2020 12:22:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44710.80114; Fri, 04 Dec 2020 12:22:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6L-0002v9-Fm; Fri, 04 Dec 2020 12:22:17 +0000
Received: by outflank-mailman (input) for mailman id 44710;
 Fri, 04 Dec 2020 12:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6J-0002ux-Kc
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6J-0001ES-Iu
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6J-0007r1-HZ
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=o7OlL42Wxr1TxMB6RAbTAZ0HONGj2q4XbKc1YFCnp+I=; b=v+c3vdR1iXdxX2Sxs7HpYHpuOw
	GqMnitqkE8rHD+in5P5wpbi9XeEELMmqt120gRd7gbCkVsQsAX+e1xQnvW/CWV0NMeG5q9d+sS3pJ
	DsJmKcqT2baJWI1VL3RWwUY4KuH8W3PbXqTPOKdiAIJihweaq5MMUsJCz5P1TpLR5Rg8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: move flush hypercall implementation into separate function
Message-Id: <E1klA6J-0007r1-HZ@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:15 +0000

commit c8117063f31370d4029cfb6abf15851e5394d12f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:13:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:13:22 2020 +0100

    viridian: move flush hypercall implementation into separate function
    
    This patch moves the implementation of HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST
    that is currently inline in viridian_hypercall() into a new hvcall_flush()
    function.
    
    The new function returns Xen erro values which are then dealt with
    appropriately. A return value of -ERESTART translates to viridian_hypercall()
    returning HVM_HCALL_preempted. Other return values translate to status codes
    and viridian_hypercall() returning HVM_HCALL_completed. Currently the only
    values, other than -ERESTART, returned by hvcall_flush() are 0 (indicating
    success) or -EINVAL.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 130 +++++++++++++++++++++--------------
 1 file changed, 78 insertions(+), 52 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 3dbb5c2d4c..f0b3ee65e3 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -518,6 +518,69 @@ static bool need_flush(void *ctxt, struct vcpu *v)
     return vcpu_mask & (1ul << v->vcpu_id);
 }
 
+union hypercall_input {
+    uint64_t raw;
+    struct {
+        uint16_t call_code;
+        uint16_t fast:1;
+        uint16_t rsvd1:15;
+        uint16_t rep_count:12;
+        uint16_t rsvd2:4;
+        uint16_t rep_start:12;
+        uint16_t rsvd3:4;
+    };
+};
+
+union hypercall_output {
+    uint64_t raw;
+    struct {
+        uint16_t result;
+        uint16_t rsvd1;
+        uint32_t rep_complete:12;
+        uint32_t rsvd2:20;
+    };
+};
+
+static int hvcall_flush(const union hypercall_input *input,
+                        union hypercall_output *output,
+                        paddr_t input_params_gpa,
+                        paddr_t output_params_gpa)
+{
+    struct {
+        uint64_t address_space;
+        uint64_t flags;
+        uint64_t vcpu_mask;
+    } input_params;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    /*
+     * It is not clear from the spec. if we are supposed to
+     * include current virtual CPU in the set or not in this case,
+     * so err on the safe side.
+     */
+    if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
+        input_params.vcpu_mask = ~0ul;
+
+    /*
+     * A false return means that another vcpu is currently trying
+     * a similar operation, so back off.
+     */
+    if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+        return -ERESTART;
+
+    output->rep_complete = input->rep_count;
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
@@ -525,29 +588,8 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
     uint16_t status = HV_STATUS_SUCCESS;
-
-    union hypercall_input {
-        uint64_t raw;
-        struct {
-            uint16_t call_code;
-            uint16_t fast:1;
-            uint16_t rsvd1:15;
-            uint16_t rep_count:12;
-            uint16_t rsvd2:4;
-            uint16_t rep_start:12;
-            uint16_t rsvd3:4;
-        };
-    } input;
-
-    union hypercall_output {
-        uint64_t raw;
-        struct {
-            uint16_t result;
-            uint16_t rsvd1;
-            uint32_t rep_complete:12;
-            uint32_t rsvd2:20;
-        };
-    } output = { 0 };
+    union hypercall_input input;
+    union hypercall_output output = {};
 
     ASSERT(is_viridian_domain(currd));
 
@@ -580,41 +622,25 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
     {
-        struct {
-            uint64_t address_space;
-            uint64_t flags;
-            uint64_t vcpu_mask;
-        } input_params;
+        int rc = hvcall_flush(&input, &output, input_params_gpa,
+                              output_params_gpa);
 
-        /* These hypercalls should never use the fast-call convention. */
-        status = HV_STATUS_INVALID_PARAMETER;
-        if ( input.fast )
-            break;
-
-        /* Get input parameters. */
-        if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
-                                      sizeof(input_params)) !=
-             HVMTRANS_okay )
+        switch ( rc )
+        {
+        case 0:
             break;
 
-        /*
-         * It is not clear from the spec. if we are supposed to
-         * include current virtual CPU in the set or not in this case,
-         * so err on the safe side.
-         */
-        if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
-            input_params.vcpu_mask = ~0ul;
-
-        /*
-         * A false return means that another vcpu is currently trying
-         * a similar operation, so back off.
-         */
-        if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+        case -ERESTART:
             return HVM_HCALL_preempted;
 
-        output.rep_complete = input.rep_count;
+        default:
+            ASSERT_UNREACHABLE();
+            /* Fallthrough */
+        case -EINVAL:
+            status = HV_STATUS_INVALID_PARAMETER;
+            break;
+        }
 
-        status = HV_STATUS_SUCCESS;
         break;
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44711.80117 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6V-0002wr-KM; Fri, 04 Dec 2020 12:22:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44711.80117; Fri, 04 Dec 2020 12:22:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6V-0002wj-HV; Fri, 04 Dec 2020 12:22:27 +0000
Received: by outflank-mailman (input) for mailman id 44711;
 Fri, 04 Dec 2020 12:22:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6T-0002wZ-QE
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6T-0001Eg-Od
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6T-0007rg-LW
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OjnKYUczNNr1KZrHepzA7aIoZ/Ef1YdvioCYCsQXpCs=; b=a0S8FXGnyJEz4DnQ56eZipG7l0
	Mt9N0uZ7q75js924pq/LYzRfrtTpWaZHsfmJrJCykrOeq0O+TuaehZmUIOnDwJhBqBRT8uJOSIyBP
	0GdAyPSF88GYSGn6woXBMOT2nAghLve0+uLJLSV6bcNfalpW8qWr2q3ZuXjWxx/9+ka8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: move IPI hypercall implementation into separate function
Message-Id: <E1klA6T-0007rg-LW@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:25 +0000

commit 905d931bcafa7be77dfe21ee5a839286bb52cfaa
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:13:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:13:41 2020 +0100

    viridian: move IPI hypercall implementation into separate function
    
    This patch moves the implementation of HVCALL_SEND_IPI that is currently
    inline in viridian_hypercall() into a new hvcall_ipi() function.
    
    The new function returns Xen errno values similarly to hvcall_flush(). Hence
    the errno translation code in viridial_hypercall() is generalized, removing
    the need for the local 'status' variable.
    
    NOTE: The formatting of the switch statement at the top of
          viridial_hypercall() is also adjusted as per CODING_STYLE.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 168 ++++++++++++++++++-----------------
 1 file changed, 87 insertions(+), 81 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index f0b3ee65e3..77e90b502c 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -581,13 +581,72 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_ipi(const union hypercall_input *input,
+                      union hypercall_output *output,
+                      paddr_t input_params_gpa,
+                      paddr_t output_params_gpa)
+{
+    struct domain *currd = current->domain;
+    struct vcpu *v;
+    uint32_t vector;
+    uint64_t vcpu_mask;
+
+    /* Get input parameters. */
+    if ( input->fast )
+    {
+        if ( input_params_gpa >> 32 )
+            return -EINVAL;
+
+        vector = input_params_gpa;
+        vcpu_mask = output_params_gpa;
+    }
+    else
+    {
+        struct {
+            uint32_t vector;
+            uint8_t target_vtl;
+            uint8_t reserved_zero[3];
+            uint64_t vcpu_mask;
+        } input_params;
+
+        if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                      sizeof(input_params)) != HVMTRANS_okay )
+            return -EINVAL;
+
+        if ( input_params.target_vtl ||
+             input_params.reserved_zero[0] ||
+             input_params.reserved_zero[1] ||
+             input_params.reserved_zero[2] )
+            return -EINVAL;
+
+        vector = input_params.vector;
+        vcpu_mask = input_params.vcpu_mask;
+    }
+
+    if ( vector < 0x10 || vector > 0xff )
+        return -EINVAL;
+
+    for_each_vcpu ( currd, v )
+    {
+        if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
+            return -EINVAL;
+
+        if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
+            continue;
+
+        vlapic_set_irq(vcpu_vlapic(v), vector, 0);
+    }
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
-    uint16_t status = HV_STATUS_SUCCESS;
+    int rc = 0;
     union hypercall_input input;
     union hypercall_output output = {};
 
@@ -600,11 +659,13 @@ int viridian_hypercall(struct cpu_user_regs *regs)
         input_params_gpa = regs->rdx;
         output_params_gpa = regs->r8;
         break;
+
     case 4:
         input.raw = (regs->rdx << 32) | regs->eax;
         input_params_gpa = (regs->rbx << 32) | regs->ecx;
         output_params_gpa = (regs->rdi << 32) | regs->esi;
         break;
+
     default:
         goto out;
     }
@@ -616,92 +677,18 @@ int viridian_hypercall(struct cpu_user_regs *regs)
          * See section 14.5.1 of the specification.
          */
         do_sched_op(SCHEDOP_yield, guest_handle_from_ptr(NULL, void));
-        status = HV_STATUS_SUCCESS;
         break;
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
-    {
-        int rc = hvcall_flush(&input, &output, input_params_gpa,
-                              output_params_gpa);
-
-        switch ( rc )
-        {
-        case 0:
-            break;
-
-        case -ERESTART:
-            return HVM_HCALL_preempted;
-
-        default:
-            ASSERT_UNREACHABLE();
-            /* Fallthrough */
-        case -EINVAL:
-            status = HV_STATUS_INVALID_PARAMETER;
-            break;
-        }
-
+        rc = hvcall_flush(&input, &output, input_params_gpa,
+                          output_params_gpa);
         break;
-    }
 
     case HVCALL_SEND_IPI:
-    {
-        struct vcpu *v;
-        uint32_t vector;
-        uint64_t vcpu_mask;
-
-        status = HV_STATUS_INVALID_PARAMETER;
-
-        /* Get input parameters. */
-        if ( input.fast )
-        {
-            if ( input_params_gpa >> 32 )
-                break;
-
-            vector = input_params_gpa;
-            vcpu_mask = output_params_gpa;
-        }
-        else
-        {
-            struct {
-                uint32_t vector;
-                uint8_t target_vtl;
-                uint8_t reserved_zero[3];
-                uint64_t vcpu_mask;
-            } input_params;
-
-            if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
-                                          sizeof(input_params)) !=
-                 HVMTRANS_okay )
-                break;
-
-            if ( input_params.target_vtl ||
-                 input_params.reserved_zero[0] ||
-                 input_params.reserved_zero[1] ||
-                 input_params.reserved_zero[2] )
-                break;
-
-            vector = input_params.vector;
-            vcpu_mask = input_params.vcpu_mask;
-        }
-
-        if ( vector < 0x10 || vector > 0xff )
-            break;
-
-        for_each_vcpu ( currd, v )
-        {
-            if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
-                break;
-
-            if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
-                continue;
-
-            vlapic_set_irq(vcpu_vlapic(v), vector, 0);
-        }
-
-        status = HV_STATUS_SUCCESS;
+        rc = hvcall_ipi(&input, &output, input_params_gpa,
+                        output_params_gpa);
         break;
-    }
 
     default:
         gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n",
@@ -714,12 +701,31 @@ int viridian_hypercall(struct cpu_user_regs *regs)
          * Given that return a status of 'invalid code' has not so far
          * caused any problems it's not worth logging.
          */
-        status = HV_STATUS_INVALID_HYPERCALL_CODE;
+        rc = -EOPNOTSUPP;
         break;
     }
 
  out:
-    output.result = status;
+    switch ( rc )
+    {
+    case 0:
+        break;
+
+    case -ERESTART:
+        return HVM_HCALL_preempted;
+
+    case -EOPNOTSUPP:
+        output.result = HV_STATUS_INVALID_HYPERCALL_CODE;
+        break;
+
+    default:
+        ASSERT_UNREACHABLE();
+        /* Fallthrough */
+    case -EINVAL:
+        output.result = HV_STATUS_INVALID_PARAMETER;
+        break;
+    }
+
     switch ( mode )
     {
     case 8:
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44712.80122 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6f-0002yf-M7; Fri, 04 Dec 2020 12:22:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44712.80122; Fri, 04 Dec 2020 12:22:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6f-0002yY-J8; Fri, 04 Dec 2020 12:22:37 +0000
Received: by outflank-mailman (input) for mailman id 44712;
 Fri, 04 Dec 2020 12:22:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6d-0002yO-TR
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6d-0001Ev-SZ
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6d-0007sK-R7
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=V8S/H7JHsYl62SW9yUfhdH3PBkZs2KUveQpV4jpDeVs=; b=o1Aho/1owVCJ/f4hJZftcgSz+C
	PHbI5dkaGyRq0ML+jGuvoyBBBYY/KIMiqPINbKzZe89LDrL0SfQfW8R4s8Rnkn22b7WeDmiq8tP/K
	b4vCgdVYtpHYmi1qQ5u5qV/hLcALvs8NHRhXJj4uOzmFqPqEzQUz0+JFbtLBfVNtl/cU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: introduce a per-cpu hypercall_vpmask and accessor functions...
Message-Id: <E1klA6d-0007sK-R7@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:35 +0000

commit 33c1a1c378e38d73d1b35b4bec6bdcd94bae41c2
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:03 2020 +0100

    viridian: introduce a per-cpu hypercall_vpmask and accessor functions...
    
    ... and make use of them in hvcall_flush()/need_flush().
    
    Subsequent patches will need to deal with virtual processor masks potentially
    wider than 64 bits. Thus, to avoid using too much stack, this patch
    introduces global per-cpu virtual processor masks and converts the
    implementation of hvcall_flush() to use them.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 58 +++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 77e90b502c..0274c8f2ee 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -507,15 +507,59 @@ void viridian_domain_deinit(struct domain *d)
     XFREE(d->arch.hvm.viridian);
 }
 
+struct hypercall_vpmask {
+    DECLARE_BITMAP(mask, HVM_MAX_VCPUS);
+};
+
+static DEFINE_PER_CPU(struct hypercall_vpmask, hypercall_vpmask);
+
+static void vpmask_empty(struct hypercall_vpmask *vpmask)
+{
+    bitmap_zero(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static void vpmask_set(struct hypercall_vpmask *vpmask, unsigned int vp,
+                       uint64_t mask)
+{
+    unsigned int count = sizeof(mask) * 8;
+
+    while ( count-- )
+    {
+        if ( !mask )
+            break;
+
+        if ( mask & 1 )
+        {
+            ASSERT(vp < HVM_MAX_VCPUS);
+            __set_bit(vp, vpmask->mask);
+        }
+
+        mask >>= 1;
+        vp++;
+    }
+}
+
+static void vpmask_fill(struct hypercall_vpmask *vpmask)
+{
+    bitmap_fill(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static bool vpmask_test(const struct hypercall_vpmask *vpmask,
+                        unsigned int vp)
+{
+    ASSERT(vp < HVM_MAX_VCPUS);
+    return test_bit(vp, vpmask->mask);
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
  */
 static bool need_flush(void *ctxt, struct vcpu *v)
 {
-    uint64_t vcpu_mask = *(uint64_t *)ctxt;
+    struct hypercall_vpmask *vpmask = ctxt;
 
-    return vcpu_mask & (1ul << v->vcpu_id);
+    return vpmask_test(vpmask, v->vcpu_id);
 }
 
 union hypercall_input {
@@ -546,6 +590,7 @@ static int hvcall_flush(const union hypercall_input *input,
                         paddr_t input_params_gpa,
                         paddr_t output_params_gpa)
 {
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
     struct {
         uint64_t address_space;
         uint64_t flags;
@@ -567,13 +612,18 @@ static int hvcall_flush(const union hypercall_input *input,
      * so err on the safe side.
      */
     if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
-        input_params.vcpu_mask = ~0ul;
+        vpmask_fill(vpmask);
+    else
+    {
+        vpmask_empty(vpmask);
+        vpmask_set(vpmask, 0, input_params.vcpu_mask);
+    }
 
     /*
      * A false return means that another vcpu is currently trying
      * a similar operation, so back off.
      */
-    if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+    if ( !paging_flush_tlb(need_flush, vpmask) )
         return -ERESTART;
 
     output->rep_complete = input->rep_count;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44713.80125 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6p-000301-Nk; Fri, 04 Dec 2020 12:22:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44713.80125; Fri, 04 Dec 2020 12:22:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6p-0002zu-Km; Fri, 04 Dec 2020 12:22:47 +0000
Received: by outflank-mailman (input) for mailman id 44713;
 Fri, 04 Dec 2020 12:22:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6o-0002zj-0s
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6o-0001FB-05
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6n-0007su-V2
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QhH949klILQFZZnO9F/JGJte9dlYeFb9QlSpC/w4BUw=; b=LWmLNnAOr8+UhQE8Ws8KoKKWz2
	+hd1wGQEqe29M8Yh2mG18dC4Y/rcMSWK52jecWW49Tr/6s3nbdl837F4mhwY9lVWN4RQFKjQu4e14
	eV3Q2scNCeaOPs9xZ2YZ2IM/sr5gCZ9L8zWzhUNZfyk68Y59f1rMko+MPdHb9zamx76Q=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: use hypercall_vpmask in hvcall_ipi()
Message-Id: <E1klA6n-0007su-V2@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:45 +0000

commit 728acba1ba4ad6f9b69fd6929362a9750fe4dbe8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:25 2020 +0100

    viridian: use hypercall_vpmask in hvcall_ipi()
    
    A subsequent patch will need to IPI a mask of virtual processors potentially
    wider than 64 bits. A previous patch introduced per-cpu hypercall_vpmask
    to allow hvcall_flush() to deal with such wide masks. This patch modifies
    the implementation of hvcall_ipi() to make use of the same mask structures,
    introducing a for_each_vp() macro to facilitate traversing a mask.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 44 +++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 0274c8f2ee..3e2393be41 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -551,6 +551,26 @@ static bool vpmask_test(const struct hypercall_vpmask *vpmask,
     return test_bit(vp, vpmask->mask);
 }
 
+static unsigned int vpmask_first(const struct hypercall_vpmask *vpmask)
+{
+    return find_first_bit(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static unsigned int vpmask_next(const struct hypercall_vpmask *vpmask,
+                                unsigned int vp)
+{
+    /*
+     * If vp + 1 > HVM_MAX_VCPUS then find_next_bit() will return
+     * HVM_MAX_VCPUS, ensuring the for_each_vp ( ... ) loop terminates.
+     */
+    return find_next_bit(vpmask->mask, HVM_MAX_VCPUS, vp + 1);
+}
+
+#define for_each_vp(vpmask, vp) \
+	for ( (vp) = vpmask_first(vpmask); \
+	      (vp) < HVM_MAX_VCPUS; \
+	      (vp) = vpmask_next(vpmask, vp) )
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -631,13 +651,21 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
+{
+    struct domain *currd = current->domain;
+    unsigned int vp;
+
+    for_each_vp ( vpmask, vp )
+        vlapic_set_irq(vcpu_vlapic(currd->vcpu[vp]), vector, 0);
+}
+
 static int hvcall_ipi(const union hypercall_input *input,
                       union hypercall_output *output,
                       paddr_t input_params_gpa,
                       paddr_t output_params_gpa)
 {
-    struct domain *currd = current->domain;
-    struct vcpu *v;
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
     uint32_t vector;
     uint64_t vcpu_mask;
 
@@ -676,16 +704,10 @@ static int hvcall_ipi(const union hypercall_input *input,
     if ( vector < 0x10 || vector > 0xff )
         return -EINVAL;
 
-    for_each_vcpu ( currd, v )
-    {
-        if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
-            return -EINVAL;
+    vpmask_empty(vpmask);
+    vpmask_set(vpmask, 0, vcpu_mask);
 
-        if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
-            continue;
-
-        vlapic_set_irq(vcpu_vlapic(v), vector, 0);
-    }
+    send_ipi(vpmask, vector);
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:22:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:22:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44714.80130 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6z-00037p-Qf; Fri, 04 Dec 2020 12:22:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44714.80130; Fri, 04 Dec 2020 12:22:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA6z-00037h-Nd; Fri, 04 Dec 2020 12:22:57 +0000
Received: by outflank-mailman (input) for mailman id 44714;
 Fri, 04 Dec 2020 12:22:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6y-00036w-45
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6y-0001G2-3F
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA6y-0007te-2U
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:22:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/lKI/mNGtO5Ab1v1UIFLKOyLK1fGBqSleRgwM5Zianc=; b=rbLNvi+Cb7nOc9YeRYuEgatehm
	3vVQoNxxEyRVYsJkUpZifJ87wNd3DqB8TZMx8yDm+IYxl++ycIFiHPxDTdKRpw4vR90MKdEtbqviJ
	6rO3+4mhlvEPvljjDvja84VnFbz7GFJrpVt4wudwg9UT2mH5g8wQiYuyypbxjoM422kg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: use softirq batching in hvcall_ipi()
Message-Id: <E1klA6y-0007te-2U@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:22:56 +0000

commit 3a3f4f00afcdcf2cdae47319168b8dadab41c4f4
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:42 2020 +0100

    viridian: use softirq batching in hvcall_ipi()
    
    vlapic_ipi() uses a softirq batching mechanism to improve the efficiency of
    sending a IPIs to large number of processors. This patch modifies send_ipi()
    (the worker function called by hvcall_ipi()) to also make use of the
    mechanism when there multiple bits set the hypercall_vpmask.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 3e2393be41..894946abcb 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -11,6 +11,7 @@
 #include <xen/hypercall.h>
 #include <xen/domain_page.h>
 #include <xen/param.h>
+#include <xen/softirq.h>
 #include <asm/guest/hyperv-tlfs.h>
 #include <asm/paging.h>
 #include <asm/p2m.h>
@@ -571,6 +572,11 @@ static unsigned int vpmask_next(const struct hypercall_vpmask *vpmask,
 	      (vp) < HVM_MAX_VCPUS; \
 	      (vp) = vpmask_next(vpmask, vp) )
 
+static unsigned int vpmask_nr(const struct hypercall_vpmask *vpmask)
+{
+    return bitmap_weight(vpmask->mask, HVM_MAX_VCPUS);
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -654,10 +660,17 @@ static int hvcall_flush(const union hypercall_input *input,
 static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
 {
     struct domain *currd = current->domain;
+    unsigned int nr = vpmask_nr(vpmask);
     unsigned int vp;
 
+    if ( nr > 1 )
+        cpu_raise_softirq_batch_begin();
+
     for_each_vp ( vpmask, vp )
         vlapic_set_irq(vcpu_vlapic(currd->vcpu[vp]), vector, 0);
+
+    if ( nr > 1 )
+        cpu_raise_softirq_batch_finish();
 }
 
 static int hvcall_ipi(const union hypercall_input *input,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44717.80134 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA79-0003Af-SY; Fri, 04 Dec 2020 12:23:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44717.80134; Fri, 04 Dec 2020 12:23:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA79-0003AX-P5; Fri, 04 Dec 2020 12:23:07 +0000
Received: by outflank-mailman (input) for mailman id 44717;
 Fri, 04 Dec 2020 12:23:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA78-0003A8-85
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA78-0001GT-6t
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA78-0007um-5l
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Q7xYgG156PqmS6PJ9n8GZLq5sWdF9bn25IxkTp+p7+g=; b=cy5yNgGRAgpc8FJmcTdfn9m1v4
	4zZm5QSmMssc+aFYKU0fiJZjP9ZLRPwtn5IdIb07TVl4vMmLzHS2DBDWt6oahJoX5+bam95Y3LQdL
	XjIDfEfdmpXpOA+FDWuQaOlmLz6GdmkkeAL7KItoyvuF1tj8SeXdaNiTs+5U3tAeYLuA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: add ExProcessorMasks variants of the flush hypercalls
Message-Id: <E1klA78-0007um-5l@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:06 +0000

commit b4124682db6ead82e856c1d406b5e7590afc228e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:59 2020 +0100

    viridian: add ExProcessorMasks variants of the flush hypercalls
    
    The Microsoft Hypervisor TLFS specifies variants of the already implemented
    HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST hypercalls that take a 'Virtual
    Processor Set' as an argument rather than a simple 64-bit mask.
    
    This patch adds a new hvcall_flush_ex() function to implement these
    (HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX) hypercalls. This makes use of
    new helper functions, hv_vpset_nr_banks() and hv_vpset_to_vpmask(), to
    determine the size of the Virtual Processor Set (so it can be copied from
    guest memory) and parse it into hypercall_vpmask (respectively).
    
    NOTE: A guest should not yet issue these hypercalls as 'ExProcessorMasks'
          support needs to be advertised via CPUID. This will be done in a
          subsequent patch.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 141 +++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 894946abcb..a4cece722e 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -577,6 +577,69 @@ static unsigned int vpmask_nr(const struct hypercall_vpmask *vpmask)
     return bitmap_weight(vpmask->mask, HVM_MAX_VCPUS);
 }
 
+#define HV_VPSET_BANK_SIZE \
+    sizeof_field(struct hv_vpset, bank_contents[0])
+
+#define HV_VPSET_SIZE(banks)   \
+    (offsetof(struct hv_vpset, bank_contents) + \
+     ((banks) * HV_VPSET_BANK_SIZE))
+
+#define HV_VPSET_MAX_BANKS \
+    (sizeof_field(struct hv_vpset, valid_bank_mask) * 8)
+
+union hypercall_vpset {
+    struct hv_vpset set;
+    uint8_t pad[HV_VPSET_SIZE(HV_VPSET_MAX_BANKS)];
+};
+
+static DEFINE_PER_CPU(union hypercall_vpset, hypercall_vpset);
+
+static unsigned int hv_vpset_nr_banks(struct hv_vpset *vpset)
+{
+    return hweight64(vpset->valid_bank_mask);
+}
+
+static uint16_t hv_vpset_to_vpmask(const struct hv_vpset *set,
+                                   struct hypercall_vpmask *vpmask)
+{
+#define NR_VPS_PER_BANK (HV_VPSET_BANK_SIZE * 8)
+
+    switch ( set->format )
+    {
+    case HV_GENERIC_SET_ALL:
+        vpmask_fill(vpmask);
+        return 0;
+
+    case HV_GENERIC_SET_SPARSE_4K:
+    {
+        uint64_t bank_mask;
+        unsigned int vp, bank = 0;
+
+        vpmask_empty(vpmask);
+        for ( vp = 0, bank_mask = set->valid_bank_mask;
+              bank_mask;
+              vp += NR_VPS_PER_BANK, bank_mask >>= 1 )
+        {
+            if ( bank_mask & 1 )
+            {
+                uint64_t mask = set->bank_contents[bank];
+
+                vpmask_set(vpmask, vp, mask);
+                bank++;
+            }
+        }
+        return 0;
+    }
+
+    default:
+        break;
+    }
+
+    return -EINVAL;
+
+#undef NR_VPS_PER_BANK
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -657,6 +720,78 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_flush_ex(const union hypercall_input *input,
+                           union hypercall_output *output,
+                           paddr_t input_params_gpa,
+                           paddr_t output_params_gpa)
+{
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
+    struct {
+        uint64_t address_space;
+        uint64_t flags;
+        struct hv_vpset set;
+    } input_params;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
+        vpmask_fill(vpmask);
+    else
+    {
+        union hypercall_vpset *vpset = &this_cpu(hypercall_vpset);
+        struct hv_vpset *set = &vpset->set;
+        size_t size;
+        int rc;
+
+        *set = input_params.set;
+        if ( set->format == HV_GENERIC_SET_SPARSE_4K )
+        {
+            unsigned long offset = offsetof(typeof(input_params),
+                                            set.bank_contents);
+
+            size = sizeof(*set->bank_contents) * hv_vpset_nr_banks(set);
+
+            if ( offsetof(typeof(*vpset), set.bank_contents[0]) + size >
+                 sizeof(*vpset) )
+            {
+                ASSERT_UNREACHABLE();
+                return -EINVAL;
+            }
+
+            if ( hvm_copy_from_guest_phys(&set->bank_contents[0],
+                                          input_params_gpa + offset,
+                                          size) != HVMTRANS_okay)
+                return -EINVAL;
+
+            size += sizeof(*set);
+        }
+        else
+            size = sizeof(*set);
+
+        rc = hv_vpset_to_vpmask(set, vpmask);
+        if ( rc )
+            return rc;
+    }
+
+    /*
+     * A false return means that another vcpu is currently trying
+     * a similar operation, so back off.
+     */
+    if ( !paging_flush_tlb(need_flush, vpmask) )
+        return -ERESTART;
+
+    output->rep_complete = input->rep_count;
+
+    return 0;
+}
+
 static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
 {
     struct domain *currd = current->domain;
@@ -770,6 +905,12 @@ int viridian_hypercall(struct cpu_user_regs *regs)
                           output_params_gpa);
         break;
 
+    case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
+    case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+        rc = hvcall_flush_ex(&input, &output, input_params_gpa,
+                             output_params_gpa);
+        break;
+
     case HVCALL_SEND_IPI:
         rc = hvcall_ipi(&input, &output, input_params_gpa,
                         output_params_gpa);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44719.80139 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7J-0003DX-U1; Fri, 04 Dec 2020 12:23:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44719.80139; Fri, 04 Dec 2020 12:23:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7J-0003DP-Qj; Fri, 04 Dec 2020 12:23:17 +0000
Received: by outflank-mailman (input) for mailman id 44719;
 Fri, 04 Dec 2020 12:23:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7I-0003DF-Au
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7I-0001Gk-AB
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7I-0007vs-9O
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/Z6Kq3lanjO4ZzwedQ1VkJIxYR/GV8nclZZ7RzWIVRM=; b=CeONE26LLclVfqHhmCSRMzp0LE
	yBN7iiXlaqE3BlZe6qzSyBFkoh2FsizOiy5xLCT9ac9H4u6nlrnmKu5v/3pzHV62JrSimens6IVjh
	fwUIR7VgK92JBE/c+aL4p+L1fSsDN/+BgiAvQ65NY8k7loO+zUQ8UNrSrO3SS8ftJTAk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: add ExProcessorMasks variant of the IPI hypercall
Message-Id: <E1klA7I-0007vs-9O@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:16 +0000

commit 9afa867d42ba1818ef0c69f787edc573c11f1f0f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:21 2020 +0100

    viridian: add ExProcessorMasks variant of the IPI hypercall
    
    A previous patch introduced variants of the flush hypercalls that take a
    'Virtual Processor Set' as an argument rather than a simple 64-bit mask.
    This patch introduces a similar variant of the HVCALL_SEND_IPI hypercall
    (HVCALL_SEND_IPI_EX).
    
    NOTE: As with HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX, a guest should
          not yet issue the HVCALL_SEND_IPI_EX hypercall as support for
          'ExProcessorMasks' is not yet advertised via CPUID.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 74 ++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index a4cece722e..5e4a2fa53a 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -860,6 +860,75 @@ static int hvcall_ipi(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_ipi_ex(const union hypercall_input *input,
+                         union hypercall_output *output,
+                         paddr_t input_params_gpa,
+                         paddr_t output_params_gpa)
+{
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
+    struct {
+        uint32_t vector;
+        uint8_t target_vtl;
+        uint8_t reserved_zero[3];
+        struct hv_vpset set;
+    } input_params;
+    union hypercall_vpset *vpset = &this_cpu(hypercall_vpset);
+    struct hv_vpset *set = &vpset->set;
+    size_t size;
+    int rc;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    if ( input_params.target_vtl ||
+         input_params.reserved_zero[0] ||
+         input_params.reserved_zero[1] ||
+         input_params.reserved_zero[2] )
+        return HV_STATUS_INVALID_PARAMETER;
+
+    if ( input_params.vector < 0x10 || input_params.vector > 0xff )
+        return HV_STATUS_INVALID_PARAMETER;
+
+    *set = input_params.set;
+    if ( set->format == HV_GENERIC_SET_SPARSE_4K )
+    {
+        unsigned long offset = offsetof(typeof(input_params),
+                                        set.bank_contents);
+
+        size = sizeof(*set->bank_contents) * hv_vpset_nr_banks(set);
+
+        if ( offsetof(typeof(*vpset), set.bank_contents[0]) + size >
+             sizeof(*vpset) )
+        {
+            ASSERT_UNREACHABLE();
+            return -EINVAL;
+        }
+
+        if ( hvm_copy_from_guest_phys(&set->bank_contents,
+                                      input_params_gpa + offset,
+                                      size) != HVMTRANS_okay)
+            return -EINVAL;
+
+        size += sizeof(*set);
+    }
+    else
+        size = sizeof(*set);
+
+    rc = hv_vpset_to_vpmask(set, vpmask);
+    if ( rc )
+        return rc;
+
+    send_ipi(vpmask, input_params.vector);
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
@@ -916,6 +985,11 @@ int viridian_hypercall(struct cpu_user_regs *regs)
                         output_params_gpa);
         break;
 
+    case HVCALL_SEND_IPI_EX:
+        rc = hvcall_ipi_ex(&input, &output, input_params_gpa,
+                           output_params_gpa);
+        break;
+
     default:
         gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n",
                 input.call_code);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44720.80141 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7T-0003Ev-VG; Fri, 04 Dec 2020 12:23:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44720.80141; Fri, 04 Dec 2020 12:23:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7T-0003En-SL; Fri, 04 Dec 2020 12:23:27 +0000
Received: by outflank-mailman (input) for mailman id 44720;
 Fri, 04 Dec 2020 12:23:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7S-0003EY-F8
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7S-0001Gw-DU
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7S-0007wo-CZ
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=r/0mhzLxjAPUdH7vj+5AOuIz7QdjMZ9B9T1yv11K6NI=; b=v2mlps3DCt50wM0RB/DSUkK8n/
	1TWT/nqKVXbVMsiSZPm8khqTNkv/wWfSk6B65HjMgbM1gfG8Tj5cM6PpmTe8I/W425PQAzdhRwvi3
	9Bith8LK1kEg4h67mLrVFsLr5UW6+3dGtBrM9oZOLWqOuuW50NdlCmNJXaCgp/kfnYx0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: log initial invocation of each type of hypercall
Message-Id: <E1klA7S-0007wo-CZ@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:26 +0000

commit 30d3cc449338546134b18ebcc2b4b435a794da17
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:38 2020 +0100

    viridian: log initial invocation of each type of hypercall
    
    To make is simpler to observe which viridian hypercalls are issued by a
    particular Windows guest, this patch adds a per-domain mask to track them.
    Each type of hypercall causes a different bit to be set in the mask and
    when the bit transitions from clear to set, a log line is emitted showing
    the name of the hypercall and the domain that issued it.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 21 +++++++++++++++++++++
 xen/include/asm-x86/hvm/viridian.h   | 10 ++++++++++
 2 files changed, 31 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 5e4a2fa53a..efd8e3a900 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -933,6 +933,7 @@ int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
+    struct viridian_domain *vd = currd->arch.hvm.viridian;
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
     int rc = 0;
@@ -962,6 +963,10 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     switch ( input.call_code )
     {
     case HVCALL_NOTIFY_LONG_SPIN_WAIT:
+        if ( !test_and_set_bit(_HCALL_spin_wait, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "d%d: VIRIDIAN HVCALL_NOTIFY_LONG_SPIN_WAIT\n",
+                   currd->domain_id);
+
         /*
          * See section 14.5.1 of the specification.
          */
@@ -970,22 +975,38 @@ int viridian_hypercall(struct cpu_user_regs *regs)
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
+        if ( !test_and_set_bit(_HCALL_flush, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST\n",
+                   currd);
+
         rc = hvcall_flush(&input, &output, input_params_gpa,
                           output_params_gpa);
         break;
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+        if ( !test_and_set_bit(_HCALL_flush_ex, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX\n",
+                   currd);
+
         rc = hvcall_flush_ex(&input, &output, input_params_gpa,
                              output_params_gpa);
         break;
 
     case HVCALL_SEND_IPI:
+        if ( !test_and_set_bit(_HCALL_ipi, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_SEND_IPI\n",
+                   currd);
+
         rc = hvcall_ipi(&input, &output, input_params_gpa,
                         output_params_gpa);
         break;
 
     case HVCALL_SEND_IPI_EX:
+        if ( !test_and_set_bit(_HCALL_ipi_ex, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_SEND_IPI_EX\n",
+                   currd);
+
         rc = hvcall_ipi_ex(&input, &output, input_params_gpa,
                            output_params_gpa);
         break;
diff --git a/xen/include/asm-x86/hvm/viridian.h b/xen/include/asm-x86/hvm/viridian.h
index cbf77d9c76..4c8ff6e80b 100644
--- a/xen/include/asm-x86/hvm/viridian.h
+++ b/xen/include/asm-x86/hvm/viridian.h
@@ -55,10 +55,20 @@ struct viridian_time_ref_count
     int64_t off;
 };
 
+enum {
+    _HCALL_spin_wait,
+    _HCALL_flush,
+    _HCALL_flush_ex,
+    _HCALL_ipi,
+    _HCALL_ipi_ex,
+    _HCALL_nr /* must be last */
+};
+
 struct viridian_domain
 {
     union hv_guest_os_id guest_os_id;
     union hv_vp_assist_page_msr hypercall_gpa;
+    DECLARE_BITMAP(hypercall_flags, _HCALL_nr);
     struct viridian_time_ref_count time_ref_count;
     struct viridian_page reference_tsc;
 };
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44721.80147 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7e-0003J3-1i; Fri, 04 Dec 2020 12:23:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44721.80147; Fri, 04 Dec 2020 12:23:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7d-0003Io-Tp; Fri, 04 Dec 2020 12:23:37 +0000
Received: by outflank-mailman (input) for mailman id 44721;
 Fri, 04 Dec 2020 12:23:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7c-0003Ie-Hd
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7c-0001H8-Gy
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7c-0007xn-G1
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Arh6hMgjoubnqSZaEPGcO4x/+LkKIih8dYmJP3kKBJc=; b=iuxhspnIbtDMfu5FPOOkQKqQO0
	VVg/aFzVaN4YhdIazg1C4l4TUMm/6VUxRfS4UhNgoGGSS+KE82HycXhf5y9n6z78IRVfanNPqhwr5
	idnaxi3mDxdvOUXgBgNY7QaFGLFHHDp+GiK4BMrngU9TXAio17mb0bVG2BOT1oE//1/o=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] viridian: add a new '_HVMPV_ex_processor_masks' bit into HVM_PARAM_VIRIDIAN...
Message-Id: <E1klA7c-0007xn-G1@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:36 +0000

commit 948719f3bf66ba0cd4ee7053185cf2befea325e8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:57 2020 +0100

    viridian: add a new '_HVMPV_ex_processor_masks' bit into HVM_PARAM_VIRIDIAN...
    
    ... and advertise ExProcessorMasks support if it is set.
    
    Support is advertised by setting bit 11 in CPUID:40000004:EAX.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 3 +++
 xen/include/public/hvm/params.h      | 7 ++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index efd8e3a900..ed978047c1 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -84,6 +84,7 @@ typedef union _HV_CRASH_CTL_REG_CONTENTS
 #define CPUID4A_MSR_BASED_APIC         (1 << 3)
 #define CPUID4A_RELAX_TIMER_INT        (1 << 5)
 #define CPUID4A_SYNTHETIC_CLUSTER_IPI  (1 << 10)
+#define CPUID4A_EX_PROCESSOR_MASKS     (1 << 11)
 
 /* Viridian CPUID leaf 6: Implementation HW features detected and in use */
 #define CPUID6A_APIC_OVERLAY    (1 << 0)
@@ -197,6 +198,8 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf,
             res->a |= CPUID4A_MSR_BASED_APIC;
         if ( viridian_feature_mask(d) & HVMPV_hcall_ipi )
             res->a |= CPUID4A_SYNTHETIC_CLUSTER_IPI;
+        if ( viridian_feature_mask(d) & HVMPV_ex_processor_masks )
+            res->a |= CPUID4A_EX_PROCESSOR_MASKS;
 
         /*
          * This value is the recommended number of attempts to try to
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 0e3fdca096..3b0a0f45da 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -164,6 +164,10 @@
 #define _HVMPV_hcall_ipi 9
 #define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi)
 
+/* Enable ExProcessorMasks */
+#define _HVMPV_ex_processor_masks 10
+#define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks)
+
 #define HVMPV_feature_mask \
         (HVMPV_base_freq | \
          HVMPV_no_freq | \
@@ -174,7 +178,8 @@
          HVMPV_crash_ctl | \
          HVMPV_synic | \
          HVMPV_stimer | \
-         HVMPV_hcall_ipi)
+         HVMPV_hcall_ipi | \
+         HVMPV_ex_processor_masks)
 
 #endif
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44722.80150 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7o-0003KJ-2T; Fri, 04 Dec 2020 12:23:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44722.80150; Fri, 04 Dec 2020 12:23:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7n-0003KB-VM; Fri, 04 Dec 2020 12:23:47 +0000
Received: by outflank-mailman (input) for mailman id 44722;
 Fri, 04 Dec 2020 12:23:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7m-0003K0-M8
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7m-0001HI-LS
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7m-0007yl-KQ
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/Pdxe3rwYyMEYEYOkrgM9YR2vBa7ycKsojOxfU3hUrM=; b=cG7X5PM1CkMFluh4sLqsNr4WK8
	LoyK5QiDSZQ5xgSWDguWUtyk5pEj6pY55GD88056BbyL8/vUH/LlvZzXu0WNqOhlpJRRjZKjyMfc8
	b23TDRaZ+3I24GdP2GdFX7zu72GBn+/eCdpCVRxWK3yXBLHr5OtUQcan3af0iD3NgRN4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xl / libxl: add 'ex_processor_mask' into 'libxl_viridian_enlightenment'
Message-Id: <E1klA7m-0007yl-KQ@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:46 +0000

commit 1e83722addc318e19a8dc4093cb6b7259c4a12b8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:16:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:16:22 2020 +0100

    xl / libxl: add 'ex_processor_mask' into 'libxl_viridian_enlightenment'
    
    Adding the new value into the enumeration makes it immediately available
    to xl, so this patch adjusts the xl.cfg(5) documentation accordingly.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.cfg.5.pod.in         | 8 ++++++++
 tools/include/libxl.h            | 7 +++++++
 tools/libs/light/libxl_types.idl | 1 +
 tools/libs/light/libxl_x86.c     | 3 +++
 4 files changed, 19 insertions(+)

diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index b4625f56db..12201a7e54 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -2318,6 +2318,14 @@ This set incorporates use of a hypercall for interprocessor interrupts.
 This enlightenment may improve performance of Windows guests with multiple
 virtual CPUs.
 
+=item B<ex_processor_masks>
+
+This set enables new hypercall variants taking a variably-sized sparse
+B<Virtual Processor Set> as an argument, rather than a simple 64-bit
+mask. Hence this enlightenment must be specified for guests with more
+than 64 vCPUs if B<hcall_remote_tlb_flush> and/or B<hcall_ipi> are also
+specified.
+
 =item B<defaults>
 
 This is a special value that enables the default set of groups, which
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 1ea5b4f446..eaffccb30f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -444,6 +444,13 @@
  */
 #define LIBXL_HAVE_DISK_SAFE_REMOVE 1
 
+/*
+ * LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS indicates that the
+ * 'ex_processor_masks' value is present in the viridian enlightenment
+ * enumeration.
+ */
+#define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 9d3f05f399..05324736b7 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -238,6 +238,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [
     (7, "synic"),
     (8, "stimer"),
     (9, "hcall_ipi"),
+    (10, "ex_processor_masks"),
     ])
 
 libxl_hdtype = Enumeration("hdtype", [
diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c
index e18274cc10..86d272999d 100644
--- a/tools/libs/light/libxl_x86.c
+++ b/tools/libs/light/libxl_x86.c
@@ -366,6 +366,9 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid,
     if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_HCALL_IPI))
         mask |= HVMPV_hcall_ipi;
 
+    if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_EX_PROCESSOR_MASKS))
+        mask |= HVMPV_ex_processor_masks;
+
     if (mask != 0 &&
         xc_hvm_param_set(CTX->xch,
                          domid,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:23:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:23:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44723.80155 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7x-0003Mn-6L; Fri, 04 Dec 2020 12:23:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44723.80155; Fri, 04 Dec 2020 12:23:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA7x-0003Mf-36; Fri, 04 Dec 2020 12:23:57 +0000
Received: by outflank-mailman (input) for mailman id 44723;
 Fri, 04 Dec 2020 12:23:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7w-0003MZ-PS
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7w-0001Ht-Ok
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA7w-0007zX-Nw
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:23:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=J1PoMid2mvQ7ZksV3zEVUT5FzCaG+FGdzC7ti43pb1g=; b=xkiaxFkd3cPG2yaiy7ExQfywvJ
	w/jRYx+lDSG4wz915lUmmRmc0bu8CeXfEhzPuRLMqwqQVBRnT1nR23t6aWZMoyj+hO/pVYqSWTUHl
	IactVlREhnLpqJd3WHq9PF/B5WDs4d8XYaX5vqhTooGNeAw8d3Q9ba7qa4Rosh8Wf+Ds=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/IRQ: drop three unused variables
Message-Id: <E1klA7w-0007zX-Nw@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:23:56 +0000

commit bfc78f77d03cfc038921ca337cc22bc25e84a877
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 13:16:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:16:49 2020 +0100

    x86/IRQ: drop three unused variables
    
    I didn't bother figuring which commit(s) should have deleted them while
    removing their last uses.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/irq.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 8d1f9a9fc6..0f2c491edc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1402,7 +1402,6 @@ void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
 {
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
-    int                 irq;
 
     if ( !(desc->status & IRQ_GUEST) )
     {
@@ -1411,7 +1410,6 @@ void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
     }
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( unlikely(!test_and_clear_bool(pirq->masked)) ||
          unlikely(--action->in_flight != 0) )
@@ -1531,7 +1529,6 @@ int pirq_shared(struct domain *d, int pirq)
 
 int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 {
-    unsigned int        irq;
     struct irq_desc         *desc;
     irq_guest_action_t *action, *newaction = NULL;
     int                 rc = 0;
@@ -1548,7 +1545,6 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
     }
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( !(desc->status & IRQ_GUEST) )
     {
@@ -1663,13 +1659,11 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 static irq_guest_action_t *__pirq_guest_unbind(
     struct domain *d, struct pirq *pirq, struct irq_desc *desc)
 {
-    unsigned int        irq;
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
     int                 i;
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( unlikely(action == NULL) )
     {
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 12:24:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 12:24:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44724.80158 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA88-0003OF-7e; Fri, 04 Dec 2020 12:24:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44724.80158; Fri, 04 Dec 2020 12:24:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klA88-0003O6-4k; Fri, 04 Dec 2020 12:24:08 +0000
Received: by outflank-mailman (input) for mailman id 44724;
 Fri, 04 Dec 2020 12:24:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA86-0003Nz-TD
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:24:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA86-0001IH-SV
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:24:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klA86-000826-RR
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 12:24:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XT43YJzplTnukOloHnr40BK50ipabP+binCgZJX+1as=; b=5QIs/A4ltQkT3fuNO2tqTVjqwz
	x2kvxpaY6CnyCjYkErwQpjrWbrbURxIVcHgkjhvtxwTvqQAOgJg9/YM5eMvkAXOdW+4a43VXuMCpU
	iu7AXwrntGV0yxvyU9SALiBCq4SnJZQHzDZ3ybAqxbBBTa+q/0Eb7f6ARdFQh+uFQCdM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/IRQ: reduce casting involved in guest action retrieval
Message-Id: <E1klA86-000826-RR@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 12:24:06 +0000

commit a00b271677bfa6365cd0446e09a0f41017e166d3
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 13:17:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:17:24 2020 +0100

    x86/IRQ: reduce casting involved in guest action retrieval
    
    Introduce a helper function covering both the IRQ_GUEST check and the
    cast involved in obtaining the (correctly typed) pointer. Where possible
    add const and/or reduce variable scope.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/irq.c | 76 ++++++++++++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 45 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 0f2c491edc..3387c1b5c3 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1042,6 +1042,11 @@ typedef struct {
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
+static irq_guest_action_t *guest_action(const struct irq_desc *desc)
+{
+    return desc->status & IRQ_GUEST ? (void *)desc->action : NULL;
+}
+
 /*
  * Stack of interrupts awaiting EOI on each CPU. These must be popped in
  * order, as only the current highest-priority pending irq can be EOIed.
@@ -1111,11 +1116,9 @@ static void irq_guest_eoi_timer_fn(void *data)
 
     spin_lock_irq(&desc->lock);
     
-    if ( !(desc->status & IRQ_GUEST) )
+    if ( !(action = guest_action(desc)) )
         goto out;
 
-    action = (irq_guest_action_t *)desc->action;
-
     ASSERT(action->ack_type != ACKTYPE_NONE);
 
     /*
@@ -1351,16 +1354,15 @@ static void flush_ready_eoi(void)
     pending_eoi_sp(peoi) = sp+1;
 }
 
-static void __set_eoi_ready(struct irq_desc *desc)
+static void __set_eoi_ready(const struct irq_desc *desc)
 {
-    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    irq_guest_action_t *action = guest_action(desc);
     struct pending_eoi *peoi = this_cpu(pending_eoi);
     int                 irq, sp;
 
     irq = desc - irq_desc;
 
-    if ( !(desc->status & IRQ_GUEST) ||
-         (action->in_flight != 0) ||
+    if ( !action || action->in_flight ||
          !cpumask_test_and_clear_cpu(smp_processor_id(),
                                      action->cpu_eoi_map) )
         return;
@@ -1400,18 +1402,11 @@ void pirq_guest_eoi(struct pirq *pirq)
 
 void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
 {
-    irq_guest_action_t *action;
+    irq_guest_action_t *action = guest_action(desc);
     cpumask_t           cpu_eoi_map;
 
-    if ( !(desc->status & IRQ_GUEST) )
-    {
-        spin_unlock_irq(&desc->lock);
-        return;
-    }
-
-    action = (irq_guest_action_t *)desc->action;
-
-    if ( unlikely(!test_and_clear_bool(pirq->masked)) ||
+    if ( unlikely(!action) ||
+         unlikely(!test_and_clear_bool(pirq->masked)) ||
          unlikely(--action->in_flight != 0) )
     {
         spin_unlock_irq(&desc->lock);
@@ -1510,8 +1505,8 @@ static int irq_acktype(const struct irq_desc *desc)
 
 int pirq_shared(struct domain *d, int pirq)
 {
-    struct irq_desc         *desc;
-    irq_guest_action_t *action;
+    struct irq_desc    *desc;
+    const irq_guest_action_t *action;
     unsigned long       flags;
     int                 shared;
 
@@ -1519,8 +1514,8 @@ int pirq_shared(struct domain *d, int pirq)
     if ( desc == NULL )
         return 0;
 
-    action = (irq_guest_action_t *)desc->action;
-    shared = ((desc->status & IRQ_GUEST) && (action->nr_guests > 1));
+    action = guest_action(desc);
+    shared = (action && (action->nr_guests > 1));
 
     spin_unlock_irqrestore(&desc->lock, flags);
 
@@ -1544,9 +1539,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto out;
     }
 
-    action = (irq_guest_action_t *)desc->action;
-
-    if ( !(desc->status & IRQ_GUEST) )
+    if ( !(action = guest_action(desc)) )
     {
         if ( desc->action != NULL )
         {
@@ -1659,21 +1652,18 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 static irq_guest_action_t *__pirq_guest_unbind(
     struct domain *d, struct pirq *pirq, struct irq_desc *desc)
 {
-    irq_guest_action_t *action;
+    irq_guest_action_t *action = guest_action(desc);
     cpumask_t           cpu_eoi_map;
     int                 i;
 
-    action = (irq_guest_action_t *)desc->action;
-
     if ( unlikely(action == NULL) )
     {
         dprintk(XENLOG_G_WARNING, "dom%d: pirq %d: desc->action is NULL!\n",
                 d->domain_id, pirq->pirq);
+        BUG_ON(!(desc->status & IRQ_GUEST));
         return NULL;
     }
 
-    BUG_ON(!(desc->status & IRQ_GUEST));
-
     for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ )
         continue;
     BUG_ON(i == action->nr_guests);
@@ -1793,14 +1783,12 @@ static bool pirq_guest_force_unbind(struct domain *d, struct pirq *pirq)
     desc = pirq_spin_lock_irq_desc(pirq, NULL);
     BUG_ON(desc == NULL);
 
-    if ( !(desc->status & IRQ_GUEST) )
-        goto out;
-
-    action = (irq_guest_action_t *)desc->action;
+    action = guest_action(desc);
     if ( unlikely(action == NULL) )
     {
-        dprintk(XENLOG_G_WARNING, "dom%d: pirq %d: desc->action is NULL!\n",
-            d->domain_id, pirq->pirq);
+        if ( desc->status & IRQ_GUEST )
+            dprintk(XENLOG_G_WARNING, "%pd: pirq %d: desc->action is NULL!\n",
+                    d, pirq->pirq);
         goto out;
     }
 
@@ -1827,7 +1815,7 @@ static bool pirq_guest_force_unbind(struct domain *d, struct pirq *pirq)
 
 static void do_IRQ_guest(struct irq_desc *desc, unsigned int vector)
 {
-    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    irq_guest_action_t *action = guest_action(desc);
     unsigned int        i;
     struct pending_eoi *peoi = this_cpu(pending_eoi);
 
@@ -2444,7 +2432,6 @@ static void dump_irqs(unsigned char key)
 {
     int i, irq, pirq;
     struct irq_desc *desc;
-    irq_guest_action_t *action;
     struct domain *d;
     const struct pirq *info;
     unsigned long flags;
@@ -2454,6 +2441,8 @@ static void dump_irqs(unsigned char key)
 
     for ( irq = 0; irq < nr_irqs; irq++ )
     {
+        const irq_guest_action_t *action;
+
         if ( !(irq & 0x1f) )
             process_pending_softirqs();
 
@@ -2473,10 +2462,9 @@ static void dump_irqs(unsigned char key)
         if ( ssid )
             printk("Z=%-25s ", ssid);
 
-        if ( desc->status & IRQ_GUEST )
+        action = guest_action(desc);
+        if ( action )
         {
-            action = (irq_guest_action_t *)desc->action;
-
             printk("in-flight=%d%c",
                    action->in_flight, action->nr_guests ? ' ' : '\n');
 
@@ -2651,17 +2639,15 @@ void fixup_irqs(const cpumask_t *mask, bool verbose)
 void fixup_eoi(void)
 {
     unsigned int irq, sp;
-    struct irq_desc *desc;
-    irq_guest_action_t *action;
     struct pending_eoi *peoi;
 
     /* Clean up cpu_eoi_map of every interrupt to exclude this CPU. */
     for ( irq = 0; irq < nr_irqs; irq++ )
     {
-        desc = irq_to_desc(irq);
-        if ( !(desc->status & IRQ_GUEST) )
+        irq_guest_action_t *action = guest_action(irq_to_desc(irq));
+
+        if ( !action )
             continue;
-        action = (irq_guest_action_t *)desc->action;
         cpumask_clear_cpu(smp_processor_id(), action->cpu_eoi_map);
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 04 13:44:12 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 04 Dec 2020 13:44:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.44778.80237 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klBNW-0003qh-0S; Fri, 04 Dec 2020 13:44:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 44778.80237; Fri, 04 Dec 2020 13:44:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klBNV-0003qZ-Tg; Fri, 04 Dec 2020 13:44:05 +0000
Received: by outflank-mailman (input) for mailman id 44778;
 Fri, 04 Dec 2020 13:44:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klBNV-0003qU-6N
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 13:44:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klBNV-00034O-2z
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 13:44:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klBNV-0006G9-0q
 for xen-changelog@lists.xenproject.org; Fri, 04 Dec 2020 13:44:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xON7JlkQKnK1NwWY1cZmVk6PPl0+3mVQyB/WooGcr7U=; b=qIn4rVsL2mqDLrZ+WGiDscC+5/
	4J/BNvoOVYsfZqQgE+50fTnL1LxRbcD2Cd+RDnVKgiOkAcSNM5JvyEnb8rRV4tJpi4cEjkhKCEfX9
	oyG+pL+gW58sIl4uupXQNt0eUEjYdikN0cmtL1rVNoW1PbM9gmldW9uCAtzcB2fJwPMs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/libs/ctrl: fix dumping of ballooned guest
Message-Id: <E1klBNV-0006G9-0q@xenbits.xenproject.org>
Date: Fri, 04 Dec 2020 13:44:05 +0000

commit 5e666356a9d55fbd9eb5b8506088aa760e107b5b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Nov 11 11:01:43 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Fri Dec 4 13:35:46 2020 +0000

    tools/libs/ctrl: fix dumping of ballooned guest
    
    A guest with memory < maxmem often can't be dumped via xl dump-core
    without an error message today:
    
    xc: info: exceeded nr_pages (262144) losing pages
    
    In case the last page of the guest isn't allocated the loop in
    xc_domain_dumpcore_via_callback() will always spit out this message,
    as the number of already dumped pages is tested before the next page
    is checked to be valid.
    
    The guest's p2m_size might be lower than expected, so this should be
    tested in order to avoid reading past the end of it.
    
    The guest might use high bits in p2m entries to flag special cases like
    foreign mappings. Entries with an MFN larger than the highest MFN of
    the host should be skipped.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/libs/ctrl/xc_core.c | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/tools/libs/ctrl/xc_core.c b/tools/libs/ctrl/xc_core.c
index e8c6fb96f9..b47ab2f6d8 100644
--- a/tools/libs/ctrl/xc_core.c
+++ b/tools/libs/ctrl/xc_core.c
@@ -439,6 +439,7 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
     unsigned long i;
     unsigned long j;
     unsigned long nr_pages;
+    unsigned long max_mfn;
 
     xc_core_memory_map_t *memory_map = NULL;
     unsigned int nr_memory_map;
@@ -577,6 +578,10 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                                    &p2m, &dinfo->p2m_size);
         if ( sts != 0 )
             goto out;
+
+        sts = xc_maximum_ram_page(xch, &max_mfn);
+        if ( sts != 0 )
+            goto out;
     }
     else
     {
@@ -818,19 +823,12 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
         {
             uint64_t gmfn;
             void *vaddr;
-            
-            if ( j >= nr_pages )
-            {
-                /*
-                 * When live dump-mode (-L option) is specified,
-                 * guest domain may increase memory.
-                 */
-                IPRINTF("exceeded nr_pages (%ld) losing pages", nr_pages);
-                goto copy_done;
-            }
 
             if ( !auto_translated_physmap )
             {
+                if ( i >= dinfo->p2m_size )
+                    break;
+
                 if ( dinfo->guest_width >= sizeof(unsigned long) )
                 {
                     if ( dinfo->guest_width == sizeof(unsigned long) )
@@ -846,6 +844,14 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                     if ( gmfn == (uint32_t)INVALID_PFN )
                        continue;
                 }
+                if ( gmfn > max_mfn )
+                    continue;
+
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
 
                 p2m_array[j].pfn = i;
                 p2m_array[j].gmfn = gmfn;
@@ -855,6 +861,12 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                 if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
                     continue;
 
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
+
                 gmfn = i;
                 pfn_array[j] = i;
             }
@@ -879,7 +891,15 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
         }
     }
 
-copy_done:
+    if ( j > nr_pages )
+    {
+        /*
+         * When live dump-mode (-L option) is specified,
+         * guest domain may increase memory.
+         */
+        IPRINTF("exceeded nr_pages (%ld) losing %ld pages", nr_pages, j - nr_pages);
+    }
+
     sts = dump_rtn(xch, args, dump_mem_start, dump_mem - dump_mem_start);
     if ( sts != 0 )
         goto out;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 06:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 06:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45218.80715 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTF-0002vB-3u; Sat, 05 Dec 2020 06:55:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45218.80715; Sat, 05 Dec 2020 06:55:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTF-0002v2-0e; Sat, 05 Dec 2020 06:55:05 +0000
Received: by outflank-mailman (input) for mailman id 45218;
 Sat, 05 Dec 2020 06:55:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTC-0002uw-TG
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTC-0005W9-SN
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTC-0005YE-QO
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/uxPqow88DQ8g0vs2OBe7HSq0aG9QfUg+bI0L2EgqPI=; b=XY32GCjqglXGLDoTo6uMqWLqzM
	YB3wTZkXXm8KdPc+aUmNvaGoU/gasoqsim/dBpMl6lmTRGzDoaRSk2R9GuvnOax9uAdG5N2gUsFJw
	LhCqb+HrYosItEdySmm49ZwuEP7arpIxvv4zzW/lymZFHpeHqmhpTOoVOHslBE868xAI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] evtchn: avoid access tearing for ->virq_to_evtchn[] accesses
Message-Id: <E1klRTC-0005YE-QO@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 06:55:02 +0000

commit 8be06d7055dc73823e2dacd6da14620d6ef4beed
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 08:27:26 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:27:26 2020 +0100

    evtchn: avoid access tearing for ->virq_to_evtchn[] accesses
    
    Use {read,write}_atomic() to exclude any eventualities, in particular
    observing that accesses aren't all happening under a consistent lock.
    
    Requested-by: Julien Grall <julien@xen.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_channel.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index dbfba62a49..59f95f2eb2 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -441,7 +441,7 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     spin_lock(&d->event_lock);
 
-    if ( v->virq_to_evtchn[virq] != 0 )
+    if ( read_atomic(&v->virq_to_evtchn[virq]) )
         ERROR_EXIT(-EEXIST);
 
     if ( port != 0 )
@@ -469,7 +469,8 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
 
     evtchn_write_unlock(chn);
 
-    v->virq_to_evtchn[virq] = bind->port = port;
+    bind->port = port;
+    write_atomic(&v->virq_to_evtchn[virq], port);
 
  out:
     spin_unlock(&d->event_lock);
@@ -655,9 +656,9 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     case ECS_VIRQ:
         for_each_vcpu ( d1, v )
         {
-            if ( v->virq_to_evtchn[chn1->u.virq] != port1 )
+            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) != port1 )
                 continue;
-            v->virq_to_evtchn[chn1->u.virq] = 0;
+            write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
             spin_barrier(&v->virq_lock);
         }
         break;
@@ -796,7 +797,7 @@ bool evtchn_virq_enabled(const struct vcpu *v, unsigned int virq)
     if ( virq_is_global(virq) && v->vcpu_id )
         v = domain_vcpu(v->domain, 0);
 
-    return v->virq_to_evtchn[virq];
+    return read_atomic(&v->virq_to_evtchn[virq]);
 }
 
 void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
@@ -810,7 +811,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     spin_lock_irqsave(&v->virq_lock, flags);
 
-    port = v->virq_to_evtchn[virq];
+    port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
         goto out;
 
@@ -844,7 +845,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
 
     spin_lock_irqsave(&v->virq_lock, flags);
 
-    port = v->virq_to_evtchn[virq];
+    port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
         goto out;
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 06:55:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 06:55:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45219.80719 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTP-0002w3-5c; Sat, 05 Dec 2020 06:55:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45219.80719; Sat, 05 Dec 2020 06:55:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTP-0002vt-2C; Sat, 05 Dec 2020 06:55:15 +0000
Received: by outflank-mailman (input) for mailman id 45219;
 Sat, 05 Dec 2020 06:55:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTN-0002vh-2n
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTN-0005WC-1t
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTN-0005Yq-0h
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=mjoD4H+2EMzB+gVLTRq0ttN6K9/fMlZVkv7csqp5sWY=; b=MvnP2sOPfWNyd/tp+a6oMkBBVW
	K6Dxgp/AhGrBAVOkIOnfKqFRcnD2aIRgR6CnN02ruEHzI3LSP3wBN9Rgn12wEV8N60roAhXThkOGu
	gHzEsB2pEapXGfsKPVSpLrh73JrAaVWEySiGNgUr0+vdRqBc8NS4evX9cuchr+ogCAoU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] fix spelling errors
Message-Id: <E1klRTN-0005Yq-0h@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 06:55:13 +0000

commit ba6e78f0db820fbeea4df41fde4655020ca05928
Author:     Diederik de Haas <didi.debian@cknow.org>
AuthorDate: Fri Dec 4 08:28:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:28:21 2020 +0100

    fix spelling errors
    
    Only spelling errors; no functional changes.
    
    In docs/misc/dump-core-format.txt there are a few more instances of
    'informations'. I'll leave that up to someone who can properly determine
    how those sentences should be constructed.
    
    Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
    Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 docs/man/xl.1.pod.in                   | 2 +-
 docs/man/xl.cfg.5.pod.in               | 2 +-
 docs/man/xlcpupool.cfg.5.pod           | 2 +-
 tools/firmware/rombios/rombios.c       | 2 +-
 tools/libs/light/libxl_stream_read.c   | 2 +-
 tools/xl/xl_cmdtable.c                 | 2 +-
 xen/arch/x86/boot/video.S              | 2 +-
 xen/arch/x86/cpu/vpmu.c                | 2 +-
 xen/arch/x86/mpparse.c                 | 2 +-
 xen/arch/x86/x86_emulate/x86_emulate.c | 2 +-
 xen/common/libelf/libelf-dominfo.c     | 2 +-
 xen/drivers/passthrough/arm/smmu.c     | 2 +-
 xen/tools/gen-cpuid.py                 | 2 +-
 xen/xsm/flask/policy/access_vectors    | 2 +-
 14 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index f92bacfa72..eaa72faad6 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1578,7 +1578,7 @@ List vsnd devices for a domain.
 Creates a new keyboard device in the domain specified by I<domain-id>.
 I<vkb-device> describes the device to attach, using the same format as the
 B<VKB_SPEC_STRING> string in the domain config file. See L<xl.cfg(5)>
-for more informations.
+for more information.
 
 =item B<vkb-detach> I<domain-id> I<devid>
 
diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 0532739c1f..b4625f56db 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -2385,7 +2385,7 @@ If B<videoram> is set less than 128MB, an error will be triggered.
 
 =item B<stdvga=BOOLEAN>
 
-Speficies a standard VGA card with VBE (VESA BIOS Extensions) as the
+Specifies a standard VGA card with VBE (VESA BIOS Extensions) as the
 emulated graphics device. If your guest supports VBE 2.0 or
 later (e.g. Windows XP onwards) then you should enable this.
 stdvga supports more video ram and bigger resolutions than Cirrus.
diff --git a/docs/man/xlcpupool.cfg.5.pod b/docs/man/xlcpupool.cfg.5.pod
index 3c9ddf7958..c577c7ca3a 100644
--- a/docs/man/xlcpupool.cfg.5.pod
+++ b/docs/man/xlcpupool.cfg.5.pod
@@ -106,7 +106,7 @@ means that cpus 2,3,5 will be member of the cpupool.
 means that cpus 0,2,3 and 5 will be member of the cpupool. A "node:" or
 "nodes:" modifier can be used. E.g., "0,node:1,nodes:2-3,^10-13" means
 that pcpus 0, plus all the cpus of NUMA nodes 1,2,3 with the exception
-of cpus 10,11,12,13 will be memeber of the cpupool.
+of cpus 10,11,12,13 will be members of the cpupool.
 
 =back
 
diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c
index 51558ee57a..5cda22785f 100644
--- a/tools/firmware/rombios/rombios.c
+++ b/tools/firmware/rombios/rombios.c
@@ -2607,7 +2607,7 @@ void ata_detect( )
   write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11);
 #endif
 #if BX_MAX_ATA_INTERFACES > 4
-#error Please fill the ATA interface informations
+#error Please fill the ATA interface information
 #endif
 
   // Device detection
diff --git a/tools/libs/light/libxl_stream_read.c b/tools/libs/light/libxl_stream_read.c
index 514f6d9f89..99a6714e76 100644
--- a/tools/libs/light/libxl_stream_read.c
+++ b/tools/libs/light/libxl_stream_read.c
@@ -459,7 +459,7 @@ static void stream_continue(libxl__egc *egc,
         while (process_record(egc, stream))
             ; /*
                * Nothing! process_record() helpfully tells us if no specific
-               * futher actions have been set up, in which case we want to go
+               * further actions have been set up, in which case we want to go
                * ahead and process the next record.
                */
         break;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 7da6c1b927..6ab5e47da3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -154,7 +154,7 @@ struct cmd_spec cmd_table[] = {
       "-h  Print this help.\n"
       "-c  Leave domain running after creating the snapshot.\n"
       "-p  Leave domain paused after creating the snapshot.\n"
-      "-D  Store the domain id in the configration."
+      "-D  Store the domain id in the configuration."
     },
     { "migrate",
       &main_migrate, 0, 1,
diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S
index a485779ce7..0efbe8d3b3 100644
--- a/xen/arch/x86/boot/video.S
+++ b/xen/arch/x86/boot/video.S
@@ -177,7 +177,7 @@ dac_set:
         movb    $0, _param(PARAM_LFB_COLORS+7)
 
 dac_done:
-# get protected mode interface informations
+# get protected mode interface information
         movw    $0x4f0a, %ax
         xorw    %bx, %bx
         xorw    %di, %di
diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 1ed39ef03f..ab667361d3 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -680,7 +680,7 @@ static void pvpmu_finish(struct domain *d, xen_pmu_params_t *params)
         vcpu_unpause(v);
 }
 
-/* Dump some vpmu informations on console. Used in keyhandler dump_domains(). */
+/* Dump some vpmu information to console. Used in keyhandler dump_domains(). */
 void vpmu_dump(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index d532575fee..dff02b142b 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -170,7 +170,7 @@ static int MP_processor_info_x(struct mpc_config_processor *m,
 	if (num_processors >= 8 && hotplug
 	    && genapic.name == apic_default.name) {
 		printk_once(XENLOG_WARNING
-			    "WARNING: CPUs limit of 8 reached - ignoring futher processors\n");
+			    "WARNING: CPUs limit of 8 reached - ignoring further processors\n");
 		unaccounted_cpus = true;
 		return -ENOSPC;
 	}
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index a35b63634b..6ac0787745 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3246,7 +3246,7 @@ x86_decode(
             case 0x23: /* mov reg,dr */
                 /*
                  * Mov to/from cr/dr ignore the encoding of Mod, and behave as
-                 * if they were encoded as reg/reg instructions.  No futher
+                 * if they were encoded as reg/reg instructions.  No further
                  * disp/SIB bytes are fetched.
                  */
                 modrm_mod = 3;
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
index 508f08db42..69c94b6f3b 100644
--- a/xen/common/libelf/libelf-dominfo.c
+++ b/xen/common/libelf/libelf-dominfo.c
@@ -1,5 +1,5 @@
 /*
- * parse xen-specific informations out of elf kernel binaries.
+ * parse xen-specific information out of elf kernel binaries.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index b8321f5d8d..ed04d85e05 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -214,7 +214,7 @@ struct iommu_domain
 	struct list_head		list;
 };
 
-/* Xen: Describes informations required for a Xen domain */
+/* Xen: Describes information required for a Xen domain */
 struct arm_smmu_xen_domain {
 	spinlock_t			lock;
 	/* List of context (i.e iommu_domain) associated to this domain */
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 50412b9a46..36f67750e5 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -192,7 +192,7 @@ def crunch_numbers(state):
         FXSR: [FFXSR, SSE],
 
         # SSE is taken to mean support for the %XMM registers as well as the
-        # instructions.  Several futher instruction sets are built on core
+        # instructions.  Several further instruction sets are built on core
         # %XMM support, without specific inter-dependencies.  Additionally
         # AMD has a special mis-alignment sub-mode.
         SSE: [SSE2, MISALIGNSSE],
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 1aa0bb501c..6359c7fc87 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -507,7 +507,7 @@ class security
 #
 class version
 {
-# Extra informations (-unstable).
+# Extra information (-unstable).
     xen_extraversion
 # Compile information of the hypervisor.
     xen_compile_info
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 06:55:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 06:55:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45220.80723 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTY-0002xi-9r; Sat, 05 Dec 2020 06:55:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45220.80723; Sat, 05 Dec 2020 06:55:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTY-0002xY-6N; Sat, 05 Dec 2020 06:55:24 +0000
Received: by outflank-mailman (input) for mailman id 45220;
 Sat, 05 Dec 2020 06:55:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTX-0002xQ-70
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTX-0005X1-6C
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTX-0005ZQ-4T
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sCAHF9fufrMSmoiinL1xvKdfz3xKcCtSFxkbsdoygMQ=; b=h00tByTB9vxCDInGI3ZPH1Gez1
	JNE0bQkGHcCXPItGMptWIe9ieZEqvyfeE/02013PonDS5m9BpulOuSjR8m36KBmqF6+WNOTZRJ1IX
	D2rr7A5/gaFwoJzc8PdluUTk5818N85ZnCvs3SYxGccbJI8HL9sV0Hj+2BQ4Ag2qRFE0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/hypfs: move per-node function pointers into a dedicated struct
Message-Id: <E1klRTX-0005ZQ-4T@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 06:55:23 +0000

commit d29033719b8246d7bbef9b0fff2b6a168b7d1b56
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:29:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:29:41 2020 +0100

    xen/hypfs: move per-node function pointers into a dedicated struct
    
    Move the function pointers currently stored in each hypfs node into a
    dedicated structure in order to save some space for each node. This
    will save even more space with additional callbacks added in future.
    
    Provide some standard function vectors.
    
    Instead of testing the write pointer to be not NULL provide a dummy
    function just returning -EACCESS. ASSERT() all vector entries being
    populated when adding a node. This avoids any potential problem (e.g.
    pv domain privilege escalations) in case of calling a non populated
    vector entry.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c      | 41 +++++++++++++++++++++++-----
 xen/include/xen/hypfs.h | 71 ++++++++++++++++++++++++++++++++++---------------
 xen/include/xen/param.h | 15 ++++-------
 3 files changed, 88 insertions(+), 39 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 8e932b5cf9..7befd144ba 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -24,6 +24,27 @@ CHECK_hypfs_dirlistentry;
     (DIRENTRY_NAME_OFF +        \
      ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
 
+const struct hypfs_funcs hypfs_dir_funcs = {
+    .read = hypfs_read_dir,
+    .write = hypfs_write_deny,
+};
+const struct hypfs_funcs hypfs_leaf_ro_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_deny,
+};
+const struct hypfs_funcs hypfs_leaf_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_leaf,
+};
+const struct hypfs_funcs hypfs_bool_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_bool,
+};
+const struct hypfs_funcs hypfs_custom_wr_funcs = {
+    .read = hypfs_read_leaf,
+    .write = hypfs_write_custom,
+};
+
 static DEFINE_RWLOCK(hypfs_lock);
 enum hypfs_lock_state {
     hypfs_unlocked,
@@ -74,6 +95,9 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
     int ret = -ENOENT;
     struct hypfs_entry *e;
 
+    ASSERT(new->funcs->read);
+    ASSERT(new->funcs->write);
+
     hypfs_write_lock();
 
     list_for_each_entry ( e, &parent->dirlist, list )
@@ -284,7 +308,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
 
     guest_handle_add_offset(uaddr, sizeof(e));
 
-    ret = entry->read(entry, uaddr);
+    ret = entry->funcs->read(entry, uaddr);
 
  out:
     return ret;
@@ -297,6 +321,7 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
     int ret;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
+    ASSERT(leaf->e.max_size);
 
     if ( ulen > leaf->e.max_size )
         return -ENOSPC;
@@ -357,6 +382,7 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
     int ret;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
+    ASSERT(leaf->e.max_size);
 
     /* Avoid oversized buffer allocation. */
     if ( ulen > MAX_PARAM_SIZE )
@@ -382,19 +408,20 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
     return ret;
 }
 
+int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
+                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+{
+    return -EACCES;
+}
+
 static int hypfs_write(struct hypfs_entry *entry,
                        XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
 {
     struct hypfs_entry_leaf *l;
 
-    if ( !entry->write )
-        return -EACCES;
-
-    ASSERT(entry->max_size);
-
     l = container_of(entry, struct hypfs_entry_leaf, e);
 
-    return entry->write(l, uaddr, ulen);
+    return entry->funcs->write(l, uaddr, ulen);
 }
 
 long do_hypfs_op(unsigned int cmd,
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 5ad99cb558..25fdf3ead7 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -7,6 +7,32 @@
 #include <public/hypfs.h>
 
 struct hypfs_entry_leaf;
+struct hypfs_entry;
+
+/*
+ * Per-node callbacks:
+ *
+ * The callbacks are always called with the hypfs lock held.
+ *
+ * The read() callback is used to return the contents of a node (either
+ * directory or leaf). It is NOT used to get directory entries during traversal
+ * of the tree.
+ *
+ * The write() callback is used to modify the contents of a node. Writing
+ * directories is not supported (this means all nodes are added at boot time).
+ */
+struct hypfs_funcs {
+    int (*read)(const struct hypfs_entry *entry,
+                XEN_GUEST_HANDLE_PARAM(void) uaddr);
+    int (*write)(struct hypfs_entry_leaf *leaf,
+                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+};
+
+extern const struct hypfs_funcs hypfs_dir_funcs;
+extern const struct hypfs_funcs hypfs_leaf_ro_funcs;
+extern const struct hypfs_funcs hypfs_leaf_wr_funcs;
+extern const struct hypfs_funcs hypfs_bool_wr_funcs;
+extern const struct hypfs_funcs hypfs_custom_wr_funcs;
 
 struct hypfs_entry {
     unsigned short type;
@@ -15,10 +41,7 @@ struct hypfs_entry {
     unsigned int max_size;
     const char *name;
     struct list_head list;
-    int (*read)(const struct hypfs_entry *entry,
-                XEN_GUEST_HANDLE_PARAM(void) uaddr);
-    int (*write)(struct hypfs_entry_leaf *leaf,
-                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+    const struct hypfs_funcs *funcs;
 };
 
 struct hypfs_entry_leaf {
@@ -42,7 +65,7 @@ struct hypfs_entry_dir {
         .e.size = 0,                              \
         .e.max_size = 0,                          \
         .e.list = LIST_HEAD_INIT(var.e.list),     \
-        .e.read = hypfs_read_dir,                 \
+        .e.funcs = &hypfs_dir_funcs,              \
         .dirlist = LIST_HEAD_INIT(var.dirlist),   \
     }
 
@@ -52,7 +75,7 @@ struct hypfs_entry_dir {
         .e.encoding = XEN_HYPFS_ENC_PLAIN,        \
         .e.name = (nam),                          \
         .e.max_size = (msz),                      \
-        .e.read = hypfs_read_leaf,                \
+        .e.funcs = &hypfs_leaf_ro_funcs,          \
     }
 
 /* Content and size need to be set via hypfs_string_set_reference(). */
@@ -72,35 +95,37 @@ static inline void hypfs_string_set_reference(struct hypfs_entry_leaf *leaf,
     leaf->e.size = strlen(str) + 1;
 }
 
-#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, wr) \
-    struct hypfs_entry_leaf __read_mostly var = {        \
-        .e.type = (typ),                                 \
-        .e.encoding = XEN_HYPFS_ENC_PLAIN,               \
-        .e.name = (nam),                                 \
-        .e.size = sizeof(contvar),                       \
-        .e.max_size = (wr) ? sizeof(contvar) : 0,        \
-        .e.read = hypfs_read_leaf,                       \
-        .e.write = (wr),                                 \
-        .u.content = &(contvar),                         \
+#define HYPFS_FIXEDSIZE_INIT(var, typ, nam, contvar, fn, wr) \
+    struct hypfs_entry_leaf __read_mostly var = {            \
+        .e.type = (typ),                                     \
+        .e.encoding = XEN_HYPFS_ENC_PLAIN,                   \
+        .e.name = (nam),                                     \
+        .e.size = sizeof(contvar),                           \
+        .e.max_size = (wr) ? sizeof(contvar) : 0,            \
+        .e.funcs = (fn),                                     \
+        .u.content = &(contvar),                             \
     }
 
 #define HYPFS_UINT_INIT(var, nam, contvar)                       \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_UINT_INIT_WRITABLE(var, nam, contvar)              \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_UINT, nam, contvar, \
-                         hypfs_write_leaf)
+                         &hypfs_leaf_wr_funcs, 1)
 
 #define HYPFS_INT_INIT(var, nam, contvar)                        \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar,  \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_INT_INIT_WRITABLE(var, nam, contvar)               \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_INT, nam, contvar, \
-                         hypfs_write_leaf)
+                         &hypfs_leaf_wr_funcs, 1)
 
 #define HYPFS_BOOL_INIT(var, nam, contvar)                       \
-    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, NULL)
+    HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
+                         &hypfs_leaf_ro_funcs, 0)
 #define HYPFS_BOOL_INIT_WRITABLE(var, nam, contvar)              \
     HYPFS_FIXEDSIZE_INIT(var, XEN_HYPFS_TYPE_BOOL, nam, contvar, \
-                         hypfs_write_bool)
+                         &hypfs_bool_wr_funcs, 1)
 
 extern struct hypfs_entry_dir hypfs_root;
 
@@ -112,6 +137,8 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr);
+int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
+                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
diff --git a/xen/include/xen/param.h b/xen/include/xen/param.h
index d0409d3a0e..1b2c7db954 100644
--- a/xen/include/xen/param.h
+++ b/xen/include/xen/param.h
@@ -116,8 +116,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
         { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
           .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
           .hypfs.e.name = (nam), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_custom, \
+          .hypfs.e.funcs = &hypfs_custom_wr_funcs, \
           .init_leaf = (initfunc), \
           .func = (variable) }
 #define boolean_runtime_only_param(nam, variable) \
@@ -127,8 +126,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_bool, \
+          .hypfs.e.funcs = &hypfs_bool_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define integer_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -137,8 +135,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define size_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -147,8 +144,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = sizeof(variable), \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 #define string_runtime_only_param(nam, variable) \
     __paramfs __parfs_##variable = \
@@ -157,8 +153,7 @@ extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
           .hypfs.e.name = (nam), \
           .hypfs.e.size = 0, \
           .hypfs.e.max_size = sizeof(variable), \
-          .hypfs.e.read = hypfs_read_leaf, \
-          .hypfs.e.write = hypfs_write_leaf, \
+          .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
           .hypfs.u.content = &(variable) }
 
 #else
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 06:55:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 06:55:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45221.80727 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTi-0002zD-BD; Sat, 05 Dec 2020 06:55:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45221.80727; Sat, 05 Dec 2020 06:55:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTi-0002z5-8F; Sat, 05 Dec 2020 06:55:34 +0000
Received: by outflank-mailman (input) for mailman id 45221;
 Sat, 05 Dec 2020 06:55:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTh-0002yv-BY
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTh-0005X8-Ak
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTh-0005aE-8q
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WGqgQBVA6CCCPH7PCgKDYKhWUOJIdaYNug18TmpNBaY=; b=i8HlNtg2uurTcNtrPG3EUVh4rM
	YrbXGagb/A1bdDY9VLizLdrPFcZXMb7dCzxYiJECSRUm5m3RG6FCrpSzhJxqBCxfs+NWCzQAXLUoW
	gio885bhUEuN3OtivTTBrrltDMvU54fkJwXhp3zyX6pTHU034726Kpkbks7tipRq5sUY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/hypfs: pass real failure reason up from hypfs_get_entry()
Message-Id: <E1klRTh-0005aE-8q@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 06:55:33 +0000

commit f1b920bb06c6fb3bdad8a483fb6ecf5c76069799
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:30:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:30:17 2020 +0100

    xen/hypfs: pass real failure reason up from hypfs_get_entry()
    
    Instead of handling all errors from hypfs_get_entry() as ENOENT pass
    up the real error value via ERR_PTR().
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 7befd144ba..fdfd0f764a 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -187,7 +187,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
     while ( again )
     {
         if ( dir->e.type != XEN_HYPFS_TYPE_DIR )
-            return NULL;
+            return ERR_PTR(-ENOENT);
 
         if ( !*path )
             return &dir->e;
@@ -206,7 +206,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
                                                      struct hypfs_entry_dir, e);
 
             if ( cmp < 0 )
-                return NULL;
+                return ERR_PTR(-ENOENT);
             if ( !cmp && strlen(entry->name) == name_len )
             {
                 if ( !*end )
@@ -221,13 +221,13 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
         }
     }
 
-    return NULL;
+    return ERR_PTR(-ENOENT);
 }
 
 static struct hypfs_entry *hypfs_get_entry(const char *path)
 {
     if ( path[0] != '/' )
-        return NULL;
+        return ERR_PTR(-EINVAL);
 
     return hypfs_get_entry_rel(&hypfs_root, path + 1);
 }
@@ -454,9 +454,9 @@ long do_hypfs_op(unsigned int cmd,
         goto out;
 
     entry = hypfs_get_entry(path);
-    if ( !entry )
+    if ( IS_ERR(entry) )
     {
-        ret = -ENOENT;
+        ret = PTR_ERR(entry);
         goto out;
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 06:55:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 06:55:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45222.80731 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTs-00030T-Cj; Sat, 05 Dec 2020 06:55:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45222.80731; Sat, 05 Dec 2020 06:55:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klRTs-00030M-9n; Sat, 05 Dec 2020 06:55:44 +0000
Received: by outflank-mailman (input) for mailman id 45222;
 Sat, 05 Dec 2020 06:55:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTr-00030G-Fp
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTr-0005XM-EZ
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klRTr-0005ar-Dc
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 06:55:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aUiVCvvFFyxjd3OoaN9g+F3c51ajdiM8yO3b/ISldDo=; b=OzxDCW590G0FFa219VXzHNU3R6
	3WZHhB8KKVb9drPYMjoz+f+7HOOs/TT5eMfocHYN84DQKwBs1hzGj715TYkoSr8t9KXKuWihPQQCS
	OyB31b/hD/uBkZCQGN+yIPVl6PjrUs0hOzQu7yoLn4booBR97XDKP92v3L2DIBRfotTU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/hypfs: add getsize() and findentry() callbacks to hypfs_funcs
Message-Id: <E1klRTr-0005ar-Dc@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 06:55:43 +0000

commit be3755af37263833cb3b1c6b1f2ba219bdf97ec3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Fri Dec 4 08:31:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 08:31:25 2020 +0100

    xen/hypfs: add getsize() and findentry() callbacks to hypfs_funcs
    
    Add a getsize() function pointer to struct hypfs_funcs for being able
    to have dynamically filled entries without the need to take the hypfs
    lock each time the contents are being generated.
    
    For directories add a findentry callback to the vector and modify
    hypfs_get_entry_rel() to use it. For its non-directory node counterpart
    introduce the so far unused and hence missing ENOTDIR error code.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c         | 100 +++++++++++++++++++++++++++++----------------
 xen/include/public/errno.h |   1 +
 xen/include/xen/hypfs.h    |  25 +++++++++++-
 3 files changed, 90 insertions(+), 36 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index fdfd0f764a..2e8e90591e 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -27,22 +27,32 @@ CHECK_hypfs_dirlistentry;
 const struct hypfs_funcs hypfs_dir_funcs = {
     .read = hypfs_read_dir,
     .write = hypfs_write_deny,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_dir_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_ro_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_deny,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_leaf,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_bool_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_bool,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_custom_wr_funcs = {
     .read = hypfs_read_leaf,
     .write = hypfs_write_custom,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
 };
 
 static DEFINE_RWLOCK(hypfs_lock);
@@ -97,6 +107,8 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
 
     ASSERT(new->funcs->read);
     ASSERT(new->funcs->write);
+    ASSERT(new->funcs->getsize);
+    ASSERT(new->funcs->findentry);
 
     hypfs_write_lock();
 
@@ -176,15 +188,41 @@ static int hypfs_get_path_user(char *buf,
     return 0;
 }
 
+struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
+                                         const char *name,
+                                         unsigned int name_len)
+{
+    return ERR_PTR(-ENOTDIR);
+}
+
+struct hypfs_entry *hypfs_dir_findentry(const struct hypfs_entry_dir *dir,
+                                        const char *name,
+                                        unsigned int name_len)
+{
+    struct hypfs_entry *entry;
+
+    list_for_each_entry ( entry, &dir->dirlist, list )
+    {
+        int cmp = strncmp(name, entry->name, name_len);
+
+        if ( cmp < 0 )
+            return ERR_PTR(-ENOENT);
+
+        if ( !cmp && strlen(entry->name) == name_len )
+            return entry;
+    }
+
+    return ERR_PTR(-ENOENT);
+}
+
 static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
                                                const char *path)
 {
     const char *end;
     struct hypfs_entry *entry;
     unsigned int name_len;
-    bool again = true;
 
-    while ( again )
+    for ( ; ; )
     {
         if ( dir->e.type != XEN_HYPFS_TYPE_DIR )
             return ERR_PTR(-ENOENT);
@@ -197,28 +235,12 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
             end = strchr(path, '\0');
         name_len = end - path;
 
-        again = false;
+        entry = dir->e.funcs->findentry(dir, path, name_len);
+        if ( IS_ERR(entry) || !*end )
+            return entry;
 
-        list_for_each_entry ( entry, &dir->dirlist, list )
-        {
-            int cmp = strncmp(path, entry->name, name_len);
-            struct hypfs_entry_dir *d = container_of(entry,
-                                                     struct hypfs_entry_dir, e);
-
-            if ( cmp < 0 )
-                return ERR_PTR(-ENOENT);
-            if ( !cmp && strlen(entry->name) == name_len )
-            {
-                if ( !*end )
-                    return entry;
-
-                again = true;
-                dir = d;
-                path = end + 1;
-
-                break;
-            }
-        }
+        path = end + 1;
+        dir = container_of(entry, struct hypfs_entry_dir, e);
     }
 
     return ERR_PTR(-ENOENT);
@@ -232,12 +254,17 @@ static struct hypfs_entry *hypfs_get_entry(const char *path)
     return hypfs_get_entry_rel(&hypfs_root, path + 1);
 }
 
+unsigned int hypfs_getsize(const struct hypfs_entry *entry)
+{
+    return entry->size;
+}
+
 int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr)
 {
     const struct hypfs_entry_dir *d;
     const struct hypfs_entry *e;
-    unsigned int size = entry->size;
+    unsigned int size = entry->funcs->getsize(entry);
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
@@ -252,7 +279,7 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
         direntry.e.pad = 0;
         direntry.e.type = e->type;
         direntry.e.encoding = e->encoding;
-        direntry.e.content_len = e->size;
+        direntry.e.content_len = e->funcs->getsize(e);
         direntry.e.max_write_len = e->max_size;
         direntry.off_next = list_is_last(&e->list, &d->dirlist) ? 0 : e_len;
         if ( copy_to_guest(uaddr, &direntry, 1) )
@@ -275,18 +302,20 @@ int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr)
 {
     const struct hypfs_entry_leaf *l;
+    unsigned int size = entry->funcs->getsize(entry);
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
     l = container_of(entry, const struct hypfs_entry_leaf, e);
 
-    return copy_to_guest(uaddr, l->u.content, entry->size) ? -EFAULT: 0;
+    return copy_to_guest(uaddr, l->u.content, size) ?  -EFAULT : 0;
 }
 
 static int hypfs_read(const struct hypfs_entry *entry,
                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
 {
     struct xen_hypfs_direntry e;
+    unsigned int size = entry->funcs->getsize(entry);
     long ret = -EINVAL;
 
     if ( ulen < sizeof(e) )
@@ -295,7 +324,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
     e.pad = 0;
     e.type = entry->type;
     e.encoding = entry->encoding;
-    e.content_len = entry->size;
+    e.content_len = size;
     e.max_write_len = entry->max_size;
 
     ret = -EFAULT;
@@ -303,7 +332,7 @@ static int hypfs_read(const struct hypfs_entry *entry,
         goto out;
 
     ret = -ENOBUFS;
-    if ( ulen < entry->size + sizeof(e) )
+    if ( ulen < size + sizeof(e) )
         goto out;
 
     guest_handle_add_offset(uaddr, sizeof(e));
@@ -319,15 +348,16 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
 {
     char *buf;
     int ret;
+    struct hypfs_entry *e = &leaf->e;
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
     ASSERT(leaf->e.max_size);
 
-    if ( ulen > leaf->e.max_size )
+    if ( ulen > e->max_size )
         return -ENOSPC;
 
-    if ( leaf->e.type != XEN_HYPFS_TYPE_STRING &&
-         leaf->e.type != XEN_HYPFS_TYPE_BLOB && ulen != leaf->e.size )
+    if ( e->type != XEN_HYPFS_TYPE_STRING &&
+         e->type != XEN_HYPFS_TYPE_BLOB && ulen != e->funcs->getsize(e) )
         return -EDOM;
 
     buf = xmalloc_array(char, ulen);
@@ -339,14 +369,14 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
         goto out;
 
     ret = -EINVAL;
-    if ( leaf->e.type == XEN_HYPFS_TYPE_STRING &&
-         leaf->e.encoding == XEN_HYPFS_ENC_PLAIN &&
+    if ( e->type == XEN_HYPFS_TYPE_STRING &&
+         e->encoding == XEN_HYPFS_ENC_PLAIN &&
          memchr(buf, 0, ulen) != (buf + ulen - 1) )
         goto out;
 
     ret = 0;
     memcpy(leaf->u.write_ptr, buf, ulen);
-    leaf->e.size = ulen;
+    e->size = ulen;
 
  out:
     xfree(buf);
@@ -360,7 +390,7 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
 
     ASSERT(this_cpu(hypfs_locked) == hypfs_write_locked);
     ASSERT(leaf->e.type == XEN_HYPFS_TYPE_BOOL &&
-           leaf->e.size == sizeof(bool) &&
+           leaf->e.funcs->getsize(&leaf->e) == sizeof(bool) &&
            leaf->e.max_size == sizeof(bool) );
 
     if ( ulen != leaf->e.max_size )
diff --git a/xen/include/public/errno.h b/xen/include/public/errno.h
index e1d02fcddf..5c53af6af9 100644
--- a/xen/include/public/errno.h
+++ b/xen/include/public/errno.h
@@ -78,6 +78,7 @@ XEN_ERRNO(EBUSY,	16)	/* Device or resource busy */
 XEN_ERRNO(EEXIST,	17)	/* File exists */
 XEN_ERRNO(EXDEV,	18)	/* Cross-device link */
 XEN_ERRNO(ENODEV,	19)	/* No such device */
+XEN_ERRNO(ENOTDIR,	20)	/* Not a directory */
 XEN_ERRNO(EISDIR,	21)	/* Is a directory */
 XEN_ERRNO(EINVAL,	22)	/* Invalid argument */
 XEN_ERRNO(ENFILE,	23)	/* File table overflow */
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 25fdf3ead7..53f50772b4 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -2,17 +2,21 @@
 #define __XEN_HYPFS_H__
 
 #ifdef CONFIG_HYPFS
+#include <xen/lib.h>
 #include <xen/list.h>
 #include <xen/string.h>
 #include <public/hypfs.h>
 
 struct hypfs_entry_leaf;
+struct hypfs_entry_dir;
 struct hypfs_entry;
 
 /*
  * Per-node callbacks:
  *
- * The callbacks are always called with the hypfs lock held.
+ * The callbacks are always called with the hypfs lock held. In case multiple
+ * callbacks are called for a single operation the lock is held across all
+ * those callbacks.
  *
  * The read() callback is used to return the contents of a node (either
  * directory or leaf). It is NOT used to get directory entries during traversal
@@ -20,12 +24,24 @@ struct hypfs_entry;
  *
  * The write() callback is used to modify the contents of a node. Writing
  * directories is not supported (this means all nodes are added at boot time).
+ *
+ * getsize() is called in two cases:
+ * - when reading a node (directory or leaf) for filling in the size of the
+ *   node into the returned direntry
+ * - when reading a directory for each node in this directory
+ *
+ * findentry() is called for traversing a path from the root node to a node
+ * for all nodes on that path excluding the final node (so for looking up
+ * "/a/b/c" findentry() will be called for "/", "/a", and "/a/b").
  */
 struct hypfs_funcs {
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
                  XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+    unsigned int (*getsize)(const struct hypfs_entry *entry);
+    struct hypfs_entry *(*findentry)(const struct hypfs_entry_dir *dir,
+                                     const char *name, unsigned int name_len);
 };
 
 extern const struct hypfs_funcs hypfs_dir_funcs;
@@ -145,6 +161,13 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
                      XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
                        XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+unsigned int hypfs_getsize(const struct hypfs_entry *entry);
+struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
+                                         const char *name,
+                                         unsigned int name_len);
+struct hypfs_entry *hypfs_dir_findentry(const struct hypfs_entry_dir *dir,
+                                        const char *name,
+                                        unsigned int name_len);
 #endif
 
 #endif /* __XEN_HYPFS_H__ */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45422.80845 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUZ-0005RC-VS; Sat, 05 Dec 2020 16:33:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45422.80845; Sat, 05 Dec 2020 16:33:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUZ-0005R3-RY; Sat, 05 Dec 2020 16:33:03 +0000
Received: by outflank-mailman (input) for mailman id 45422;
 Sat, 05 Dec 2020 16:33:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUY-0005Qx-Tm
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUY-0001TT-SM
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUY-0006hu-QQ
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4HAkzMUdMkTmoGrP6Cm4dwwRbfBk0l4Um0I8Cb6c8DE=; b=MeAcG2NCmKmnr5JUxDXUm8hcQn
	VRCNoug27zuQOo7ZJssh2cODF+jyms+MLCaBRj7Y9/DJxXw9uSCQKa6z3v5GWypnvq64Hj4WgOzWn
	anOlGtMBM10+Npuy68yJ/mfSdHpg5SPLKiVD3Hc+AvU7cEIYibpmYRMdc3WXigO/B5MA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/hotplug: allow tuning of xenwatchdogd arguments
Message-Id: <E1klaUY-0006hu-QQ@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:02 +0000

commit 0fb6dbfaa859aae0e51a82a8d5e213bcc64b85f1
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Thu Dec 3 07:34:36 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Fri Dec 4 11:51:14 2020 +0000

    tools/hotplug: allow tuning of xenwatchdogd arguments
    
    Currently the arguments for xenwatchdogd are hardcoded with 15s
    keep-alive interval and 30s timeout.
    
    It is not possible to tweak these values via
    /etc/systemd/system/xen-watchdog.service.d/*.conf because ExecStart
    can not be replaced. The only option would be a private copy
    /etc/systemd/system/xen-watchdog.service, which may get out of sync
    with the Xen provided xen-watchdog.service.
    
    Adjust the service file to recognize XENWATCHDOGD_ARGS= in a
    private unit configuration file.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/hotplug/Linux/init.d/xen-watchdog.in          | 7 ++++++-
 tools/hotplug/Linux/systemd/xen-watchdog.service.in | 4 +++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/hotplug/Linux/init.d/xen-watchdog.in b/tools/hotplug/Linux/init.d/xen-watchdog.in
index c05f1f6b6a..a0bde199c4 100644
--- a/tools/hotplug/Linux/init.d/xen-watchdog.in
+++ b/tools/hotplug/Linux/init.d/xen-watchdog.in
@@ -19,6 +19,11 @@
 
 . @XEN_SCRIPT_DIR@/hotplugpath.sh
 
+xencommons_config=@CONFIG_DIR@/@CONFIG_LEAF_DIR@
+
+test -f $xencommons_config/xencommons && . $xencommons_config/xencommons
+
+test -n "$XENWATCHDOGD_ARGS" || XENWATCHDOGD_ARGS='30 15'
 DAEMON=${sbindir}/xenwatchdogd
 base=$(basename $DAEMON)
 
@@ -46,7 +51,7 @@ start() {
 	local r
 	echo -n $"Starting domain watchdog daemon: "
 
-	$DAEMON 30 15
+	$DAEMON $XENWATCHDOGD_ARGS
 	r=$?
 	[ "$r" -eq 0 ] && success $"$base startup" || failure $"$base startup"
 	echo
diff --git a/tools/hotplug/Linux/systemd/xen-watchdog.service.in b/tools/hotplug/Linux/systemd/xen-watchdog.service.in
index 1eecd2a616..637ab7fd7f 100644
--- a/tools/hotplug/Linux/systemd/xen-watchdog.service.in
+++ b/tools/hotplug/Linux/systemd/xen-watchdog.service.in
@@ -6,7 +6,9 @@ ConditionPathExists=/proc/xen/capabilities
 
 [Service]
 Type=forking
-ExecStart=@sbindir@/xenwatchdogd 30 15
+Environment="XENWATCHDOGD_ARGS=30 15"
+EnvironmentFile=-@CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons
+ExecStart=@sbindir@/xenwatchdogd $XENWATCHDOGD_ARGS
 KillSignal=USR1
 
 [Install]
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45423.80847 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUj-0005Tl-WC; Sat, 05 Dec 2020 16:33:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45423.80847; Sat, 05 Dec 2020 16:33:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUj-0005Td-T3; Sat, 05 Dec 2020 16:33:13 +0000
Received: by outflank-mailman (input) for mailman id 45423;
 Sat, 05 Dec 2020 16:33:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUj-0005TY-0g
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUi-0001Te-W8
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUi-0006iQ-V6
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9bLtVLJWsYrgNet1dXuqkKcCu4iiVZYYPrcjpx/EHLM=; b=Ib5rNZLWJ2nvsv+OHf5xguiJSk
	7QIzYVyi0L46Bfx8Taxo+8p3T2uO2YwQZBEADlJe5HgMB2MDXHctPeSzpO7GT/l5oV+l/i8PmIJYZ
	yGR/MW+22WfL5eWJALr2BDQrXZS5VNy2Kck1vHTyBjOG49Lqy3AxhvlK2O1lmn7Y90rQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: don't blindly write to 32-bit registers if 'mode' is invalid
Message-Id: <E1klaUi-0006iQ-V6@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:12 +0000

commit 7c8946dae39b544094d969ef902d49e8ea0ea973
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:12:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:12:54 2020 +0100

    viridian: don't blindly write to 32-bit registers if 'mode' is invalid
    
    If hvm_guest_x86_mode() returns something other than 8 or 4 then
    viridian_hypercall() will return immediately but, on the way out, will write
    back status as if 'mode' was 4. This patch simply makes it leave the registers
    alone.
    
    NOTE: The formatting of the 'out' label and the switch statement are also
          adjusted as per CODING_STYLE.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index dc7183a546..3dbb5c2d4c 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -692,13 +692,15 @@ int viridian_hypercall(struct cpu_user_regs *regs)
         break;
     }
 
-out:
+ out:
     output.result = status;
-    switch (mode) {
+    switch ( mode )
+    {
     case 8:
         regs->rax = output.raw;
         break;
-    default:
+
+    case 4:
         regs->rdx = output.raw >> 32;
         regs->rax = (uint32_t)output.raw;
         break;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45424.80851 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUv-0005Vl-1m; Sat, 05 Dec 2020 16:33:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45424.80851; Sat, 05 Dec 2020 16:33:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaUu-0005Vb-Ug; Sat, 05 Dec 2020 16:33:24 +0000
Received: by outflank-mailman (input) for mailman id 45424;
 Sat, 05 Dec 2020 16:33:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUt-0005VN-5v
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUt-0001Tl-3O
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaUt-0006j0-2Q
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=L2T+IEU4WcdZ1TzzJmF/Omee1IDpVRczvru/GGaX9SU=; b=n/Z825Y0VIEXT4p9KvKUFUI+cK
	eY6ZCJ+oGX0eiETmnvttNpIWWovuYmF1WzZlziXLQzyEneofFDrcQ5QhZ3fJdl/irzkWGMWIg3obn
	6gi4D4vAMnnomb+W9XEco7oe6qcgtxbrv70O8EV9enIMQi0RvBPCmNNTxlWJUSgOee2A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: move flush hypercall implementation into separate function
Message-Id: <E1klaUt-0006j0-2Q@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:23 +0000

commit c8117063f31370d4029cfb6abf15851e5394d12f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:13:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:13:22 2020 +0100

    viridian: move flush hypercall implementation into separate function
    
    This patch moves the implementation of HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST
    that is currently inline in viridian_hypercall() into a new hvcall_flush()
    function.
    
    The new function returns Xen erro values which are then dealt with
    appropriately. A return value of -ERESTART translates to viridian_hypercall()
    returning HVM_HCALL_preempted. Other return values translate to status codes
    and viridian_hypercall() returning HVM_HCALL_completed. Currently the only
    values, other than -ERESTART, returned by hvcall_flush() are 0 (indicating
    success) or -EINVAL.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 130 +++++++++++++++++++++--------------
 1 file changed, 78 insertions(+), 52 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 3dbb5c2d4c..f0b3ee65e3 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -518,6 +518,69 @@ static bool need_flush(void *ctxt, struct vcpu *v)
     return vcpu_mask & (1ul << v->vcpu_id);
 }
 
+union hypercall_input {
+    uint64_t raw;
+    struct {
+        uint16_t call_code;
+        uint16_t fast:1;
+        uint16_t rsvd1:15;
+        uint16_t rep_count:12;
+        uint16_t rsvd2:4;
+        uint16_t rep_start:12;
+        uint16_t rsvd3:4;
+    };
+};
+
+union hypercall_output {
+    uint64_t raw;
+    struct {
+        uint16_t result;
+        uint16_t rsvd1;
+        uint32_t rep_complete:12;
+        uint32_t rsvd2:20;
+    };
+};
+
+static int hvcall_flush(const union hypercall_input *input,
+                        union hypercall_output *output,
+                        paddr_t input_params_gpa,
+                        paddr_t output_params_gpa)
+{
+    struct {
+        uint64_t address_space;
+        uint64_t flags;
+        uint64_t vcpu_mask;
+    } input_params;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    /*
+     * It is not clear from the spec. if we are supposed to
+     * include current virtual CPU in the set or not in this case,
+     * so err on the safe side.
+     */
+    if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
+        input_params.vcpu_mask = ~0ul;
+
+    /*
+     * A false return means that another vcpu is currently trying
+     * a similar operation, so back off.
+     */
+    if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+        return -ERESTART;
+
+    output->rep_complete = input->rep_count;
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
@@ -525,29 +588,8 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
     uint16_t status = HV_STATUS_SUCCESS;
-
-    union hypercall_input {
-        uint64_t raw;
-        struct {
-            uint16_t call_code;
-            uint16_t fast:1;
-            uint16_t rsvd1:15;
-            uint16_t rep_count:12;
-            uint16_t rsvd2:4;
-            uint16_t rep_start:12;
-            uint16_t rsvd3:4;
-        };
-    } input;
-
-    union hypercall_output {
-        uint64_t raw;
-        struct {
-            uint16_t result;
-            uint16_t rsvd1;
-            uint32_t rep_complete:12;
-            uint32_t rsvd2:20;
-        };
-    } output = { 0 };
+    union hypercall_input input;
+    union hypercall_output output = {};
 
     ASSERT(is_viridian_domain(currd));
 
@@ -580,41 +622,25 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
     {
-        struct {
-            uint64_t address_space;
-            uint64_t flags;
-            uint64_t vcpu_mask;
-        } input_params;
+        int rc = hvcall_flush(&input, &output, input_params_gpa,
+                              output_params_gpa);
 
-        /* These hypercalls should never use the fast-call convention. */
-        status = HV_STATUS_INVALID_PARAMETER;
-        if ( input.fast )
-            break;
-
-        /* Get input parameters. */
-        if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
-                                      sizeof(input_params)) !=
-             HVMTRANS_okay )
+        switch ( rc )
+        {
+        case 0:
             break;
 
-        /*
-         * It is not clear from the spec. if we are supposed to
-         * include current virtual CPU in the set or not in this case,
-         * so err on the safe side.
-         */
-        if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
-            input_params.vcpu_mask = ~0ul;
-
-        /*
-         * A false return means that another vcpu is currently trying
-         * a similar operation, so back off.
-         */
-        if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+        case -ERESTART:
             return HVM_HCALL_preempted;
 
-        output.rep_complete = input.rep_count;
+        default:
+            ASSERT_UNREACHABLE();
+            /* Fallthrough */
+        case -EINVAL:
+            status = HV_STATUS_INVALID_PARAMETER;
+            break;
+        }
 
-        status = HV_STATUS_SUCCESS;
         break;
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45425.80855 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaV5-0005X5-39; Sat, 05 Dec 2020 16:33:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45425.80855; Sat, 05 Dec 2020 16:33:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaV5-0005Wy-00; Sat, 05 Dec 2020 16:33:35 +0000
Received: by outflank-mailman (input) for mailman id 45425;
 Sat, 05 Dec 2020 16:33:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaV3-0005Wj-7f
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaV3-0001U0-6s
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaV3-0006jj-5x
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=NzCJCkiUd3d5IaJ6c7ENSMLJb55CxDl/YOdjQF/uA/g=; b=BRBD75CVZtz/LsRbRGa3DY+ia6
	C9oEWW6ZMcb8UxYZuvS63d1+Klhu617Z5tZWHHWDKyW4/zan5mz41q5YHrss5MJl+KgxsEwr/qq8V
	7yH3FW4pp0LvoSIfsVRz11DXcBNsBM+jorpiz2m0npqqOQFpey90zd/V9YtbcDBTLIBo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: move IPI hypercall implementation into separate function
Message-Id: <E1klaV3-0006jj-5x@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:33 +0000

commit 905d931bcafa7be77dfe21ee5a839286bb52cfaa
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:13:41 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:13:41 2020 +0100

    viridian: move IPI hypercall implementation into separate function
    
    This patch moves the implementation of HVCALL_SEND_IPI that is currently
    inline in viridian_hypercall() into a new hvcall_ipi() function.
    
    The new function returns Xen errno values similarly to hvcall_flush(). Hence
    the errno translation code in viridial_hypercall() is generalized, removing
    the need for the local 'status' variable.
    
    NOTE: The formatting of the switch statement at the top of
          viridial_hypercall() is also adjusted as per CODING_STYLE.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 168 ++++++++++++++++++-----------------
 1 file changed, 87 insertions(+), 81 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index f0b3ee65e3..77e90b502c 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -581,13 +581,72 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_ipi(const union hypercall_input *input,
+                      union hypercall_output *output,
+                      paddr_t input_params_gpa,
+                      paddr_t output_params_gpa)
+{
+    struct domain *currd = current->domain;
+    struct vcpu *v;
+    uint32_t vector;
+    uint64_t vcpu_mask;
+
+    /* Get input parameters. */
+    if ( input->fast )
+    {
+        if ( input_params_gpa >> 32 )
+            return -EINVAL;
+
+        vector = input_params_gpa;
+        vcpu_mask = output_params_gpa;
+    }
+    else
+    {
+        struct {
+            uint32_t vector;
+            uint8_t target_vtl;
+            uint8_t reserved_zero[3];
+            uint64_t vcpu_mask;
+        } input_params;
+
+        if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                      sizeof(input_params)) != HVMTRANS_okay )
+            return -EINVAL;
+
+        if ( input_params.target_vtl ||
+             input_params.reserved_zero[0] ||
+             input_params.reserved_zero[1] ||
+             input_params.reserved_zero[2] )
+            return -EINVAL;
+
+        vector = input_params.vector;
+        vcpu_mask = input_params.vcpu_mask;
+    }
+
+    if ( vector < 0x10 || vector > 0xff )
+        return -EINVAL;
+
+    for_each_vcpu ( currd, v )
+    {
+        if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
+            return -EINVAL;
+
+        if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
+            continue;
+
+        vlapic_set_irq(vcpu_vlapic(v), vector, 0);
+    }
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
-    uint16_t status = HV_STATUS_SUCCESS;
+    int rc = 0;
     union hypercall_input input;
     union hypercall_output output = {};
 
@@ -600,11 +659,13 @@ int viridian_hypercall(struct cpu_user_regs *regs)
         input_params_gpa = regs->rdx;
         output_params_gpa = regs->r8;
         break;
+
     case 4:
         input.raw = (regs->rdx << 32) | regs->eax;
         input_params_gpa = (regs->rbx << 32) | regs->ecx;
         output_params_gpa = (regs->rdi << 32) | regs->esi;
         break;
+
     default:
         goto out;
     }
@@ -616,92 +677,18 @@ int viridian_hypercall(struct cpu_user_regs *regs)
          * See section 14.5.1 of the specification.
          */
         do_sched_op(SCHEDOP_yield, guest_handle_from_ptr(NULL, void));
-        status = HV_STATUS_SUCCESS;
         break;
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
-    {
-        int rc = hvcall_flush(&input, &output, input_params_gpa,
-                              output_params_gpa);
-
-        switch ( rc )
-        {
-        case 0:
-            break;
-
-        case -ERESTART:
-            return HVM_HCALL_preempted;
-
-        default:
-            ASSERT_UNREACHABLE();
-            /* Fallthrough */
-        case -EINVAL:
-            status = HV_STATUS_INVALID_PARAMETER;
-            break;
-        }
-
+        rc = hvcall_flush(&input, &output, input_params_gpa,
+                          output_params_gpa);
         break;
-    }
 
     case HVCALL_SEND_IPI:
-    {
-        struct vcpu *v;
-        uint32_t vector;
-        uint64_t vcpu_mask;
-
-        status = HV_STATUS_INVALID_PARAMETER;
-
-        /* Get input parameters. */
-        if ( input.fast )
-        {
-            if ( input_params_gpa >> 32 )
-                break;
-
-            vector = input_params_gpa;
-            vcpu_mask = output_params_gpa;
-        }
-        else
-        {
-            struct {
-                uint32_t vector;
-                uint8_t target_vtl;
-                uint8_t reserved_zero[3];
-                uint64_t vcpu_mask;
-            } input_params;
-
-            if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
-                                          sizeof(input_params)) !=
-                 HVMTRANS_okay )
-                break;
-
-            if ( input_params.target_vtl ||
-                 input_params.reserved_zero[0] ||
-                 input_params.reserved_zero[1] ||
-                 input_params.reserved_zero[2] )
-                break;
-
-            vector = input_params.vector;
-            vcpu_mask = input_params.vcpu_mask;
-        }
-
-        if ( vector < 0x10 || vector > 0xff )
-            break;
-
-        for_each_vcpu ( currd, v )
-        {
-            if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
-                break;
-
-            if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
-                continue;
-
-            vlapic_set_irq(vcpu_vlapic(v), vector, 0);
-        }
-
-        status = HV_STATUS_SUCCESS;
+        rc = hvcall_ipi(&input, &output, input_params_gpa,
+                        output_params_gpa);
         break;
-    }
 
     default:
         gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n",
@@ -714,12 +701,31 @@ int viridian_hypercall(struct cpu_user_regs *regs)
          * Given that return a status of 'invalid code' has not so far
          * caused any problems it's not worth logging.
          */
-        status = HV_STATUS_INVALID_HYPERCALL_CODE;
+        rc = -EOPNOTSUPP;
         break;
     }
 
  out:
-    output.result = status;
+    switch ( rc )
+    {
+    case 0:
+        break;
+
+    case -ERESTART:
+        return HVM_HCALL_preempted;
+
+    case -EOPNOTSUPP:
+        output.result = HV_STATUS_INVALID_HYPERCALL_CODE;
+        break;
+
+    default:
+        ASSERT_UNREACHABLE();
+        /* Fallthrough */
+    case -EINVAL:
+        output.result = HV_STATUS_INVALID_PARAMETER;
+        break;
+    }
+
     switch ( mode )
     {
     case 8:
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45426.80860 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVF-0005Ya-62; Sat, 05 Dec 2020 16:33:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45426.80860; Sat, 05 Dec 2020 16:33:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVF-0005YQ-1n; Sat, 05 Dec 2020 16:33:45 +0000
Received: by outflank-mailman (input) for mailman id 45426;
 Sat, 05 Dec 2020 16:33:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVD-0005YE-Bz
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVD-0001Ul-B8
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVD-0006kd-9S
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=rl3ltaivHNXx91DkGwZgapbmWl20tKHteP9x+71+6cI=; b=cj4zoBXiAAFsxWEkMr/3q47VBQ
	hkH/7kpTGU7Orz5SpDl2kZGKrO1epdzU86fYKB7cLlOxyPrs5oCmbvMhrsRJnjcw6mapxlpP82XAn
	9dZBrj4iy2c9o6M9dxEcxwZ+Q+yiwRh8Bsz+Q/CCpMX+i7FCalS7cB6lXnKyFntLDdHU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: introduce a per-cpu hypercall_vpmask and accessor functions...
Message-Id: <E1klaVD-0006kd-9S@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:43 +0000

commit 33c1a1c378e38d73d1b35b4bec6bdcd94bae41c2
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:03 2020 +0100

    viridian: introduce a per-cpu hypercall_vpmask and accessor functions...
    
    ... and make use of them in hvcall_flush()/need_flush().
    
    Subsequent patches will need to deal with virtual processor masks potentially
    wider than 64 bits. Thus, to avoid using too much stack, this patch
    introduces global per-cpu virtual processor masks and converts the
    implementation of hvcall_flush() to use them.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 58 +++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 77e90b502c..0274c8f2ee 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -507,15 +507,59 @@ void viridian_domain_deinit(struct domain *d)
     XFREE(d->arch.hvm.viridian);
 }
 
+struct hypercall_vpmask {
+    DECLARE_BITMAP(mask, HVM_MAX_VCPUS);
+};
+
+static DEFINE_PER_CPU(struct hypercall_vpmask, hypercall_vpmask);
+
+static void vpmask_empty(struct hypercall_vpmask *vpmask)
+{
+    bitmap_zero(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static void vpmask_set(struct hypercall_vpmask *vpmask, unsigned int vp,
+                       uint64_t mask)
+{
+    unsigned int count = sizeof(mask) * 8;
+
+    while ( count-- )
+    {
+        if ( !mask )
+            break;
+
+        if ( mask & 1 )
+        {
+            ASSERT(vp < HVM_MAX_VCPUS);
+            __set_bit(vp, vpmask->mask);
+        }
+
+        mask >>= 1;
+        vp++;
+    }
+}
+
+static void vpmask_fill(struct hypercall_vpmask *vpmask)
+{
+    bitmap_fill(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static bool vpmask_test(const struct hypercall_vpmask *vpmask,
+                        unsigned int vp)
+{
+    ASSERT(vp < HVM_MAX_VCPUS);
+    return test_bit(vp, vpmask->mask);
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
  */
 static bool need_flush(void *ctxt, struct vcpu *v)
 {
-    uint64_t vcpu_mask = *(uint64_t *)ctxt;
+    struct hypercall_vpmask *vpmask = ctxt;
 
-    return vcpu_mask & (1ul << v->vcpu_id);
+    return vpmask_test(vpmask, v->vcpu_id);
 }
 
 union hypercall_input {
@@ -546,6 +590,7 @@ static int hvcall_flush(const union hypercall_input *input,
                         paddr_t input_params_gpa,
                         paddr_t output_params_gpa)
 {
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
     struct {
         uint64_t address_space;
         uint64_t flags;
@@ -567,13 +612,18 @@ static int hvcall_flush(const union hypercall_input *input,
      * so err on the safe side.
      */
     if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
-        input_params.vcpu_mask = ~0ul;
+        vpmask_fill(vpmask);
+    else
+    {
+        vpmask_empty(vpmask);
+        vpmask_set(vpmask, 0, input_params.vcpu_mask);
+    }
 
     /*
      * A false return means that another vcpu is currently trying
      * a similar operation, so back off.
      */
-    if ( !paging_flush_tlb(need_flush, &input_params.vcpu_mask) )
+    if ( !paging_flush_tlb(need_flush, vpmask) )
         return -ERESTART;
 
     output->rep_complete = input->rep_count;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:33:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:33:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45427.80863 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVP-0005a1-7t; Sat, 05 Dec 2020 16:33:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45427.80863; Sat, 05 Dec 2020 16:33:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVP-0005Zt-4y; Sat, 05 Dec 2020 16:33:55 +0000
Received: by outflank-mailman (input) for mailman id 45427;
 Sat, 05 Dec 2020 16:33:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVN-0005Zi-FK
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVN-0001Us-Eb
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVN-0006lH-DY
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:33:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PEliukSCxg3t5aCpCfDQwtXb/eBupZ5ZufWItjagz6s=; b=o1VJ4B3u71Bak3F3ZCNqga/8t5
	IPssL08dWFGggduQP41/Bbo3E63WbMI3FMW5+lYXPcMD7KTkvLO07+csbcI0iAZXibPap6LKMQAvr
	YwSKUsZ3uxcrOGd/VEQREKEUuAtNyPGK5lXSQzsfiQtBZI3uDvRxq+AaZC6SHfUJW+8E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: use hypercall_vpmask in hvcall_ipi()
Message-Id: <E1klaVN-0006lH-DY@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:33:53 +0000

commit 728acba1ba4ad6f9b69fd6929362a9750fe4dbe8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:25 2020 +0100

    viridian: use hypercall_vpmask in hvcall_ipi()
    
    A subsequent patch will need to IPI a mask of virtual processors potentially
    wider than 64 bits. A previous patch introduced per-cpu hypercall_vpmask
    to allow hvcall_flush() to deal with such wide masks. This patch modifies
    the implementation of hvcall_ipi() to make use of the same mask structures,
    introducing a for_each_vp() macro to facilitate traversing a mask.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 44 +++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 0274c8f2ee..3e2393be41 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -551,6 +551,26 @@ static bool vpmask_test(const struct hypercall_vpmask *vpmask,
     return test_bit(vp, vpmask->mask);
 }
 
+static unsigned int vpmask_first(const struct hypercall_vpmask *vpmask)
+{
+    return find_first_bit(vpmask->mask, HVM_MAX_VCPUS);
+}
+
+static unsigned int vpmask_next(const struct hypercall_vpmask *vpmask,
+                                unsigned int vp)
+{
+    /*
+     * If vp + 1 > HVM_MAX_VCPUS then find_next_bit() will return
+     * HVM_MAX_VCPUS, ensuring the for_each_vp ( ... ) loop terminates.
+     */
+    return find_next_bit(vpmask->mask, HVM_MAX_VCPUS, vp + 1);
+}
+
+#define for_each_vp(vpmask, vp) \
+	for ( (vp) = vpmask_first(vpmask); \
+	      (vp) < HVM_MAX_VCPUS; \
+	      (vp) = vpmask_next(vpmask, vp) )
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -631,13 +651,21 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
+{
+    struct domain *currd = current->domain;
+    unsigned int vp;
+
+    for_each_vp ( vpmask, vp )
+        vlapic_set_irq(vcpu_vlapic(currd->vcpu[vp]), vector, 0);
+}
+
 static int hvcall_ipi(const union hypercall_input *input,
                       union hypercall_output *output,
                       paddr_t input_params_gpa,
                       paddr_t output_params_gpa)
 {
-    struct domain *currd = current->domain;
-    struct vcpu *v;
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
     uint32_t vector;
     uint64_t vcpu_mask;
 
@@ -676,16 +704,10 @@ static int hvcall_ipi(const union hypercall_input *input,
     if ( vector < 0x10 || vector > 0xff )
         return -EINVAL;
 
-    for_each_vcpu ( currd, v )
-    {
-        if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) )
-            return -EINVAL;
+    vpmask_empty(vpmask);
+    vpmask_set(vpmask, 0, vcpu_mask);
 
-        if ( !(vcpu_mask & (1ul << v->vcpu_id)) )
-            continue;
-
-        vlapic_set_irq(vcpu_vlapic(v), vector, 0);
-    }
+    send_ipi(vpmask, vector);
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45428.80866 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVZ-0005bH-9f; Sat, 05 Dec 2020 16:34:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45428.80866; Sat, 05 Dec 2020 16:34:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVZ-0005b9-6X; Sat, 05 Dec 2020 16:34:05 +0000
Received: by outflank-mailman (input) for mailman id 45428;
 Sat, 05 Dec 2020 16:34:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVX-0005av-IU
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVX-0001VD-Hj
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVX-0006mE-H1
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=J+D6ZPk2XzT6ihV+dGabN3bHDeJb6idqERd4QNuqqk4=; b=rDut8m6GwdV2h6A0InTisAm42Y
	Q/4UMujxuefS5ZmfCmTDsbKhQJCuX6M4SSWx1wO4dmQb8480t8R3Ew46Yoe+ybu8tzuJxbWqb00rZ
	t85yz4BIJhKAiWxlSsVOsUjHxHDPcDAKjLMBAJm/s8iiLh9jrfBinTsfExVDQuRLdt6s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: use softirq batching in hvcall_ipi()
Message-Id: <E1klaVX-0006mE-H1@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:03 +0000

commit 3a3f4f00afcdcf2cdae47319168b8dadab41c4f4
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:42 2020 +0100

    viridian: use softirq batching in hvcall_ipi()
    
    vlapic_ipi() uses a softirq batching mechanism to improve the efficiency of
    sending a IPIs to large number of processors. This patch modifies send_ipi()
    (the worker function called by hvcall_ipi()) to also make use of the
    mechanism when there multiple bits set the hypercall_vpmask.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 3e2393be41..894946abcb 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -11,6 +11,7 @@
 #include <xen/hypercall.h>
 #include <xen/domain_page.h>
 #include <xen/param.h>
+#include <xen/softirq.h>
 #include <asm/guest/hyperv-tlfs.h>
 #include <asm/paging.h>
 #include <asm/p2m.h>
@@ -571,6 +572,11 @@ static unsigned int vpmask_next(const struct hypercall_vpmask *vpmask,
 	      (vp) < HVM_MAX_VCPUS; \
 	      (vp) = vpmask_next(vpmask, vp) )
 
+static unsigned int vpmask_nr(const struct hypercall_vpmask *vpmask)
+{
+    return bitmap_weight(vpmask->mask, HVM_MAX_VCPUS);
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -654,10 +660,17 @@ static int hvcall_flush(const union hypercall_input *input,
 static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
 {
     struct domain *currd = current->domain;
+    unsigned int nr = vpmask_nr(vpmask);
     unsigned int vp;
 
+    if ( nr > 1 )
+        cpu_raise_softirq_batch_begin();
+
     for_each_vp ( vpmask, vp )
         vlapic_set_irq(vcpu_vlapic(currd->vcpu[vp]), vector, 0);
+
+    if ( nr > 1 )
+        cpu_raise_softirq_batch_finish();
 }
 
 static int hvcall_ipi(const union hypercall_input *input,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45429.80871 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVj-0005cZ-BH; Sat, 05 Dec 2020 16:34:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45429.80871; Sat, 05 Dec 2020 16:34:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVj-0005cS-8C; Sat, 05 Dec 2020 16:34:15 +0000
Received: by outflank-mailman (input) for mailman id 45429;
 Sat, 05 Dec 2020 16:34:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVh-0005cD-Mi
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVh-0001VL-LV
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVh-0006ol-KX
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XqSVahZowpi4CFuMOM2pGWokMA2VkCPouAdGZH0dsf0=; b=WuaIkMiLFaZJasTlLYx1DYL04v
	PxKqexzDkQVnHnqRvG6EW0HqVFktu/LeZMcdvgxKilWCYdo6FWeYQNvG1bz16ItOktQJUsYuLPY3v
	a4ilDlpnLTdqcoVlVBtp5EgU9j/KnVhcHoFHQhX9T+2X6SMRYRMRhL6hw1e2gO4unMd4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: add ExProcessorMasks variants of the flush hypercalls
Message-Id: <E1klaVh-0006ol-KX@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:13 +0000

commit b4124682db6ead82e856c1d406b5e7590afc228e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:14:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:14:59 2020 +0100

    viridian: add ExProcessorMasks variants of the flush hypercalls
    
    The Microsoft Hypervisor TLFS specifies variants of the already implemented
    HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST hypercalls that take a 'Virtual
    Processor Set' as an argument rather than a simple 64-bit mask.
    
    This patch adds a new hvcall_flush_ex() function to implement these
    (HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX) hypercalls. This makes use of
    new helper functions, hv_vpset_nr_banks() and hv_vpset_to_vpmask(), to
    determine the size of the Virtual Processor Set (so it can be copied from
    guest memory) and parse it into hypercall_vpmask (respectively).
    
    NOTE: A guest should not yet issue these hypercalls as 'ExProcessorMasks'
          support needs to be advertised via CPUID. This will be done in a
          subsequent patch.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 141 +++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 894946abcb..a4cece722e 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -577,6 +577,69 @@ static unsigned int vpmask_nr(const struct hypercall_vpmask *vpmask)
     return bitmap_weight(vpmask->mask, HVM_MAX_VCPUS);
 }
 
+#define HV_VPSET_BANK_SIZE \
+    sizeof_field(struct hv_vpset, bank_contents[0])
+
+#define HV_VPSET_SIZE(banks)   \
+    (offsetof(struct hv_vpset, bank_contents) + \
+     ((banks) * HV_VPSET_BANK_SIZE))
+
+#define HV_VPSET_MAX_BANKS \
+    (sizeof_field(struct hv_vpset, valid_bank_mask) * 8)
+
+union hypercall_vpset {
+    struct hv_vpset set;
+    uint8_t pad[HV_VPSET_SIZE(HV_VPSET_MAX_BANKS)];
+};
+
+static DEFINE_PER_CPU(union hypercall_vpset, hypercall_vpset);
+
+static unsigned int hv_vpset_nr_banks(struct hv_vpset *vpset)
+{
+    return hweight64(vpset->valid_bank_mask);
+}
+
+static uint16_t hv_vpset_to_vpmask(const struct hv_vpset *set,
+                                   struct hypercall_vpmask *vpmask)
+{
+#define NR_VPS_PER_BANK (HV_VPSET_BANK_SIZE * 8)
+
+    switch ( set->format )
+    {
+    case HV_GENERIC_SET_ALL:
+        vpmask_fill(vpmask);
+        return 0;
+
+    case HV_GENERIC_SET_SPARSE_4K:
+    {
+        uint64_t bank_mask;
+        unsigned int vp, bank = 0;
+
+        vpmask_empty(vpmask);
+        for ( vp = 0, bank_mask = set->valid_bank_mask;
+              bank_mask;
+              vp += NR_VPS_PER_BANK, bank_mask >>= 1 )
+        {
+            if ( bank_mask & 1 )
+            {
+                uint64_t mask = set->bank_contents[bank];
+
+                vpmask_set(vpmask, vp, mask);
+                bank++;
+            }
+        }
+        return 0;
+    }
+
+    default:
+        break;
+    }
+
+    return -EINVAL;
+
+#undef NR_VPS_PER_BANK
+}
+
 /*
  * Windows should not issue the hypercalls requiring this callback in the
  * case where vcpu_id would exceed the size of the mask.
@@ -657,6 +720,78 @@ static int hvcall_flush(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_flush_ex(const union hypercall_input *input,
+                           union hypercall_output *output,
+                           paddr_t input_params_gpa,
+                           paddr_t output_params_gpa)
+{
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
+    struct {
+        uint64_t address_space;
+        uint64_t flags;
+        struct hv_vpset set;
+    } input_params;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS )
+        vpmask_fill(vpmask);
+    else
+    {
+        union hypercall_vpset *vpset = &this_cpu(hypercall_vpset);
+        struct hv_vpset *set = &vpset->set;
+        size_t size;
+        int rc;
+
+        *set = input_params.set;
+        if ( set->format == HV_GENERIC_SET_SPARSE_4K )
+        {
+            unsigned long offset = offsetof(typeof(input_params),
+                                            set.bank_contents);
+
+            size = sizeof(*set->bank_contents) * hv_vpset_nr_banks(set);
+
+            if ( offsetof(typeof(*vpset), set.bank_contents[0]) + size >
+                 sizeof(*vpset) )
+            {
+                ASSERT_UNREACHABLE();
+                return -EINVAL;
+            }
+
+            if ( hvm_copy_from_guest_phys(&set->bank_contents[0],
+                                          input_params_gpa + offset,
+                                          size) != HVMTRANS_okay)
+                return -EINVAL;
+
+            size += sizeof(*set);
+        }
+        else
+            size = sizeof(*set);
+
+        rc = hv_vpset_to_vpmask(set, vpmask);
+        if ( rc )
+            return rc;
+    }
+
+    /*
+     * A false return means that another vcpu is currently trying
+     * a similar operation, so back off.
+     */
+    if ( !paging_flush_tlb(need_flush, vpmask) )
+        return -ERESTART;
+
+    output->rep_complete = input->rep_count;
+
+    return 0;
+}
+
 static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector)
 {
     struct domain *currd = current->domain;
@@ -770,6 +905,12 @@ int viridian_hypercall(struct cpu_user_regs *regs)
                           output_params_gpa);
         break;
 
+    case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
+    case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+        rc = hvcall_flush_ex(&input, &output, input_params_gpa,
+                             output_params_gpa);
+        break;
+
     case HVCALL_SEND_IPI:
         rc = hvcall_ipi(&input, &output, input_params_gpa,
                         output_params_gpa);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45430.80875 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVt-0005eY-DF; Sat, 05 Dec 2020 16:34:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45430.80875; Sat, 05 Dec 2020 16:34:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaVt-0005eQ-A6; Sat, 05 Dec 2020 16:34:25 +0000
Received: by outflank-mailman (input) for mailman id 45430;
 Sat, 05 Dec 2020 16:34:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVr-0005eI-Pl
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVr-0001VT-Oz
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaVr-0006pg-O9
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JCFHky8oWICbSLpOQjliCJXkwA3biYYRVp8Ayqh75ww=; b=hHrIrSMKda8TJ9/WGueiOlBMha
	/HS9bPJdmPGZHBqsakBf82LF2d+/EToMpDuUzg8/9MsCYCqsAq+OeEhtGG0eYzaWW6rEbviwMBTKv
	mf1/v8kd1uckCaD6skooYPO19wvUeIwQPTL/V9XpvdPmLAUx/Zpd9UzGOTvK11I8COgs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: add ExProcessorMasks variant of the IPI hypercall
Message-Id: <E1klaVr-0006pg-O9@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:23 +0000

commit 9afa867d42ba1818ef0c69f787edc573c11f1f0f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:21 2020 +0100

    viridian: add ExProcessorMasks variant of the IPI hypercall
    
    A previous patch introduced variants of the flush hypercalls that take a
    'Virtual Processor Set' as an argument rather than a simple 64-bit mask.
    This patch introduces a similar variant of the HVCALL_SEND_IPI hypercall
    (HVCALL_SEND_IPI_EX).
    
    NOTE: As with HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX, a guest should
          not yet issue the HVCALL_SEND_IPI_EX hypercall as support for
          'ExProcessorMasks' is not yet advertised via CPUID.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 74 ++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index a4cece722e..5e4a2fa53a 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -860,6 +860,75 @@ static int hvcall_ipi(const union hypercall_input *input,
     return 0;
 }
 
+static int hvcall_ipi_ex(const union hypercall_input *input,
+                         union hypercall_output *output,
+                         paddr_t input_params_gpa,
+                         paddr_t output_params_gpa)
+{
+    struct hypercall_vpmask *vpmask = &this_cpu(hypercall_vpmask);
+    struct {
+        uint32_t vector;
+        uint8_t target_vtl;
+        uint8_t reserved_zero[3];
+        struct hv_vpset set;
+    } input_params;
+    union hypercall_vpset *vpset = &this_cpu(hypercall_vpset);
+    struct hv_vpset *set = &vpset->set;
+    size_t size;
+    int rc;
+
+    /* These hypercalls should never use the fast-call convention. */
+    if ( input->fast )
+        return -EINVAL;
+
+    /* Get input parameters. */
+    if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa,
+                                  sizeof(input_params)) != HVMTRANS_okay )
+        return -EINVAL;
+
+    if ( input_params.target_vtl ||
+         input_params.reserved_zero[0] ||
+         input_params.reserved_zero[1] ||
+         input_params.reserved_zero[2] )
+        return HV_STATUS_INVALID_PARAMETER;
+
+    if ( input_params.vector < 0x10 || input_params.vector > 0xff )
+        return HV_STATUS_INVALID_PARAMETER;
+
+    *set = input_params.set;
+    if ( set->format == HV_GENERIC_SET_SPARSE_4K )
+    {
+        unsigned long offset = offsetof(typeof(input_params),
+                                        set.bank_contents);
+
+        size = sizeof(*set->bank_contents) * hv_vpset_nr_banks(set);
+
+        if ( offsetof(typeof(*vpset), set.bank_contents[0]) + size >
+             sizeof(*vpset) )
+        {
+            ASSERT_UNREACHABLE();
+            return -EINVAL;
+        }
+
+        if ( hvm_copy_from_guest_phys(&set->bank_contents,
+                                      input_params_gpa + offset,
+                                      size) != HVMTRANS_okay)
+            return -EINVAL;
+
+        size += sizeof(*set);
+    }
+    else
+        size = sizeof(*set);
+
+    rc = hv_vpset_to_vpmask(set, vpmask);
+    if ( rc )
+        return rc;
+
+    send_ipi(vpmask, input_params.vector);
+
+    return 0;
+}
+
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
@@ -916,6 +985,11 @@ int viridian_hypercall(struct cpu_user_regs *regs)
                         output_params_gpa);
         break;
 
+    case HVCALL_SEND_IPI_EX:
+        rc = hvcall_ipi_ex(&input, &output, input_params_gpa,
+                           output_params_gpa);
+        break;
+
     default:
         gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n",
                 input.call_code);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45431.80878 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaW3-0005g1-FB; Sat, 05 Dec 2020 16:34:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45431.80878; Sat, 05 Dec 2020 16:34:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaW3-0005fs-Bl; Sat, 05 Dec 2020 16:34:35 +0000
Received: by outflank-mailman (input) for mailman id 45431;
 Sat, 05 Dec 2020 16:34:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaW1-0005fg-U2
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaW1-0001W3-Sq
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaW1-0006qe-Rl
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=R/Xxw0MDPoowzwZybeYlZB9lrNNwOCdHIPPbrYyb4XI=; b=JiiqXjWhuOffAoiKu5K1WjDtEb
	DEKbEt+XSn6zBoaBhMnptAOPQKIrFNF+wAYX4esUDyx16kxtcZPqM6ZskHWRIR88yS/WrXflEaamK
	sVINMK0Le2kt3ObUTrYyMFdXLYXHuTIdL6TpYTjSdvldeFsWHUIumDf6fy4tW9TsBJ4M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: log initial invocation of each type of hypercall
Message-Id: <E1klaW1-0006qe-Rl@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:33 +0000

commit 30d3cc449338546134b18ebcc2b4b435a794da17
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:38 2020 +0100

    viridian: log initial invocation of each type of hypercall
    
    To make is simpler to observe which viridian hypercalls are issued by a
    particular Windows guest, this patch adds a per-domain mask to track them.
    Each type of hypercall causes a different bit to be set in the mask and
    when the bit transitions from clear to set, a log line is emitted showing
    the name of the hypercall and the domain that issued it.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 21 +++++++++++++++++++++
 xen/include/asm-x86/hvm/viridian.h   | 10 ++++++++++
 2 files changed, 31 insertions(+)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 5e4a2fa53a..efd8e3a900 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -933,6 +933,7 @@ int viridian_hypercall(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
+    struct viridian_domain *vd = currd->arch.hvm.viridian;
     int mode = hvm_guest_x86_mode(curr);
     unsigned long input_params_gpa, output_params_gpa;
     int rc = 0;
@@ -962,6 +963,10 @@ int viridian_hypercall(struct cpu_user_regs *regs)
     switch ( input.call_code )
     {
     case HVCALL_NOTIFY_LONG_SPIN_WAIT:
+        if ( !test_and_set_bit(_HCALL_spin_wait, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "d%d: VIRIDIAN HVCALL_NOTIFY_LONG_SPIN_WAIT\n",
+                   currd->domain_id);
+
         /*
          * See section 14.5.1 of the specification.
          */
@@ -970,22 +975,38 @@ int viridian_hypercall(struct cpu_user_regs *regs)
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
+        if ( !test_and_set_bit(_HCALL_flush, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST\n",
+                   currd);
+
         rc = hvcall_flush(&input, &output, input_params_gpa,
                           output_params_gpa);
         break;
 
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX:
     case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX:
+        if ( !test_and_set_bit(_HCALL_flush_ex, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX\n",
+                   currd);
+
         rc = hvcall_flush_ex(&input, &output, input_params_gpa,
                              output_params_gpa);
         break;
 
     case HVCALL_SEND_IPI:
+        if ( !test_and_set_bit(_HCALL_ipi, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_SEND_IPI\n",
+                   currd);
+
         rc = hvcall_ipi(&input, &output, input_params_gpa,
                         output_params_gpa);
         break;
 
     case HVCALL_SEND_IPI_EX:
+        if ( !test_and_set_bit(_HCALL_ipi_ex, vd->hypercall_flags) )
+            printk(XENLOG_G_INFO "%pd: VIRIDIAN HVCALL_SEND_IPI_EX\n",
+                   currd);
+
         rc = hvcall_ipi_ex(&input, &output, input_params_gpa,
                            output_params_gpa);
         break;
diff --git a/xen/include/asm-x86/hvm/viridian.h b/xen/include/asm-x86/hvm/viridian.h
index cbf77d9c76..4c8ff6e80b 100644
--- a/xen/include/asm-x86/hvm/viridian.h
+++ b/xen/include/asm-x86/hvm/viridian.h
@@ -55,10 +55,20 @@ struct viridian_time_ref_count
     int64_t off;
 };
 
+enum {
+    _HCALL_spin_wait,
+    _HCALL_flush,
+    _HCALL_flush_ex,
+    _HCALL_ipi,
+    _HCALL_ipi_ex,
+    _HCALL_nr /* must be last */
+};
+
 struct viridian_domain
 {
     union hv_guest_os_id guest_os_id;
     union hv_vp_assist_page_msr hypercall_gpa;
+    DECLARE_BITMAP(hypercall_flags, _HCALL_nr);
     struct viridian_time_ref_count time_ref_count;
     struct viridian_page reference_tsc;
 };
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45432.80882 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWD-0005hW-HY; Sat, 05 Dec 2020 16:34:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45432.80882; Sat, 05 Dec 2020 16:34:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWD-0005hO-Ei; Sat, 05 Dec 2020 16:34:45 +0000
Received: by outflank-mailman (input) for mailman id 45432;
 Sat, 05 Dec 2020 16:34:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWC-0005hC-0t
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWC-0001WA-03
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWB-0006rf-VW
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=eXXClhwF21OjIJopL0IV7h0OwNMihC27p2hJpC70NXM=; b=6YxefSc0fYeNIPU87ZjtFUdj46
	ckfkZkihprhQtmj20l99yc3VZCoq6C/6ya5iM18UMxRHx6BzBc4Z00r+nlfLT7fj/d0wnTe+k/VwP
	N67xvvS4GUT1VWztjHhQLjt6iB6J+XdaxUCFAECwlQCgsozNhQhN34iw99zn2wKX2v4g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] viridian: add a new '_HVMPV_ex_processor_masks' bit into HVM_PARAM_VIRIDIAN...
Message-Id: <E1klaWB-0006rf-VW@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:43 +0000

commit 948719f3bf66ba0cd4ee7053185cf2befea325e8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:15:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:15:57 2020 +0100

    viridian: add a new '_HVMPV_ex_processor_masks' bit into HVM_PARAM_VIRIDIAN...
    
    ... and advertise ExProcessorMasks support if it is set.
    
    Support is advertised by setting bit 11 in CPUID:40000004:EAX.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/hvm/viridian/viridian.c | 3 +++
 xen/include/public/hvm/params.h      | 7 ++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index efd8e3a900..ed978047c1 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -84,6 +84,7 @@ typedef union _HV_CRASH_CTL_REG_CONTENTS
 #define CPUID4A_MSR_BASED_APIC         (1 << 3)
 #define CPUID4A_RELAX_TIMER_INT        (1 << 5)
 #define CPUID4A_SYNTHETIC_CLUSTER_IPI  (1 << 10)
+#define CPUID4A_EX_PROCESSOR_MASKS     (1 << 11)
 
 /* Viridian CPUID leaf 6: Implementation HW features detected and in use */
 #define CPUID6A_APIC_OVERLAY    (1 << 0)
@@ -197,6 +198,8 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf,
             res->a |= CPUID4A_MSR_BASED_APIC;
         if ( viridian_feature_mask(d) & HVMPV_hcall_ipi )
             res->a |= CPUID4A_SYNTHETIC_CLUSTER_IPI;
+        if ( viridian_feature_mask(d) & HVMPV_ex_processor_masks )
+            res->a |= CPUID4A_EX_PROCESSOR_MASKS;
 
         /*
          * This value is the recommended number of attempts to try to
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 0e3fdca096..3b0a0f45da 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -164,6 +164,10 @@
 #define _HVMPV_hcall_ipi 9
 #define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi)
 
+/* Enable ExProcessorMasks */
+#define _HVMPV_ex_processor_masks 10
+#define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks)
+
 #define HVMPV_feature_mask \
         (HVMPV_base_freq | \
          HVMPV_no_freq | \
@@ -174,7 +178,8 @@
          HVMPV_crash_ctl | \
          HVMPV_synic | \
          HVMPV_stimer | \
-         HVMPV_hcall_ipi)
+         HVMPV_hcall_ipi | \
+         HVMPV_ex_processor_masks)
 
 #endif
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:34:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:34:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45433.80887 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWM-0005ij-Jc; Sat, 05 Dec 2020 16:34:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45433.80887; Sat, 05 Dec 2020 16:34:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWM-0005iX-GF; Sat, 05 Dec 2020 16:34:54 +0000
Received: by outflank-mailman (input) for mailman id 45433;
 Sat, 05 Dec 2020 16:34:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWM-0005iS-4g
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWM-0001WI-3t
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWM-0006sd-2u
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:34:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=osjK39S0o/zXY4L4Tk7P4CG6tFt/n2bDRL72xa7FDOQ=; b=YbaulQJfIA8zMwCed3JL3LgaV9
	y13eCdZNflF6Ay5f0pPzr6bNZKPboAbcH1lBYGM6zjsK6QVo+Ks89AquqyPD5q8MRsQ+HRhhIiKnL
	kZJNq2BgIM93al2uIgne5POGQdXAzh5nwVQ2ADimILCi2bfqqkm0Qt79DXn88vboo5sI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xl / libxl: add 'ex_processor_mask' into 'libxl_viridian_enlightenment'
Message-Id: <E1klaWM-0006sd-2u@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:34:54 +0000

commit 1e83722addc318e19a8dc4093cb6b7259c4a12b8
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Fri Dec 4 13:16:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:16:22 2020 +0100

    xl / libxl: add 'ex_processor_mask' into 'libxl_viridian_enlightenment'
    
    Adding the new value into the enumeration makes it immediately available
    to xl, so this patch adjusts the xl.cfg(5) documentation accordingly.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.cfg.5.pod.in         | 8 ++++++++
 tools/include/libxl.h            | 7 +++++++
 tools/libs/light/libxl_types.idl | 1 +
 tools/libs/light/libxl_x86.c     | 3 +++
 4 files changed, 19 insertions(+)

diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index b4625f56db..12201a7e54 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -2318,6 +2318,14 @@ This set incorporates use of a hypercall for interprocessor interrupts.
 This enlightenment may improve performance of Windows guests with multiple
 virtual CPUs.
 
+=item B<ex_processor_masks>
+
+This set enables new hypercall variants taking a variably-sized sparse
+B<Virtual Processor Set> as an argument, rather than a simple 64-bit
+mask. Hence this enlightenment must be specified for guests with more
+than 64 vCPUs if B<hcall_remote_tlb_flush> and/or B<hcall_ipi> are also
+specified.
+
 =item B<defaults>
 
 This is a special value that enables the default set of groups, which
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 1ea5b4f446..eaffccb30f 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -444,6 +444,13 @@
  */
 #define LIBXL_HAVE_DISK_SAFE_REMOVE 1
 
+/*
+ * LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS indicates that the
+ * 'ex_processor_masks' value is present in the viridian enlightenment
+ * enumeration.
+ */
+#define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 9d3f05f399..05324736b7 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -238,6 +238,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [
     (7, "synic"),
     (8, "stimer"),
     (9, "hcall_ipi"),
+    (10, "ex_processor_masks"),
     ])
 
 libxl_hdtype = Enumeration("hdtype", [
diff --git a/tools/libs/light/libxl_x86.c b/tools/libs/light/libxl_x86.c
index e18274cc10..86d272999d 100644
--- a/tools/libs/light/libxl_x86.c
+++ b/tools/libs/light/libxl_x86.c
@@ -366,6 +366,9 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid,
     if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_HCALL_IPI))
         mask |= HVMPV_hcall_ipi;
 
+    if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_EX_PROCESSOR_MASKS))
+        mask |= HVMPV_ex_processor_masks;
+
     if (mask != 0 &&
         xc_hvm_param_set(CTX->xch,
                          domid,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:35:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:35:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45434.80891 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWW-0005k2-L7; Sat, 05 Dec 2020 16:35:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45434.80891; Sat, 05 Dec 2020 16:35:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWW-0005ju-Ho; Sat, 05 Dec 2020 16:35:04 +0000
Received: by outflank-mailman (input) for mailman id 45434;
 Sat, 05 Dec 2020 16:35:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWW-0005jm-8B
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWW-0001Wo-7R
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWW-0006tt-6X
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tki07gHYvvsCuHRrsp9Xp12I2mQW5UvDo60UUa4ul70=; b=Ut0CAJabJFl0SAwvZdUn7H56PG
	qHEkiZ+5MtBCQEa8T924zjD3LedjFJSk0vbcvCIxJE4I50WT/HsHbIx13pFL+7+c7TY7ryZmg0dbA
	I89gvgOxpM3XvonGhU23tVPA4K3FAAl2fU4vE9Lt7doQZvFgFVwgSBr9QR07PC/MajMk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/IRQ: drop three unused variables
Message-Id: <E1klaWW-0006tt-6X@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:35:04 +0000

commit bfc78f77d03cfc038921ca337cc22bc25e84a877
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 13:16:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:16:49 2020 +0100

    x86/IRQ: drop three unused variables
    
    I didn't bother figuring which commit(s) should have deleted them while
    removing their last uses.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/irq.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 8d1f9a9fc6..0f2c491edc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1402,7 +1402,6 @@ void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
 {
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
-    int                 irq;
 
     if ( !(desc->status & IRQ_GUEST) )
     {
@@ -1411,7 +1410,6 @@ void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
     }
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( unlikely(!test_and_clear_bool(pirq->masked)) ||
          unlikely(--action->in_flight != 0) )
@@ -1531,7 +1529,6 @@ int pirq_shared(struct domain *d, int pirq)
 
 int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 {
-    unsigned int        irq;
     struct irq_desc         *desc;
     irq_guest_action_t *action, *newaction = NULL;
     int                 rc = 0;
@@ -1548,7 +1545,6 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
     }
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( !(desc->status & IRQ_GUEST) )
     {
@@ -1663,13 +1659,11 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 static irq_guest_action_t *__pirq_guest_unbind(
     struct domain *d, struct pirq *pirq, struct irq_desc *desc)
 {
-    unsigned int        irq;
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
     int                 i;
 
     action = (irq_guest_action_t *)desc->action;
-    irq = desc - irq_desc;
 
     if ( unlikely(action == NULL) )
     {
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:35:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:35:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45435.80895 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWh-0005lG-MS; Sat, 05 Dec 2020 16:35:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45435.80895; Sat, 05 Dec 2020 16:35:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWh-0005l8-Jd; Sat, 05 Dec 2020 16:35:15 +0000
Received: by outflank-mailman (input) for mailman id 45435;
 Sat, 05 Dec 2020 16:35:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWg-0005l0-Bs
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWg-0001Ww-BB
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWg-0006ux-AH
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+XSCSCfFTfEjW1qVjLJ2QN1s5pvKPl1UQMiVc2a1bgg=; b=5mXixmJvlDn9pawC3VcvlZl86O
	5gSEmhFbm15rt2qPonuZFA9Y4xVm1QpHxmjE96a9kks7BIRuCLlui2DU41pU8wXCVhpvt6oAoYF+d
	j99nTGRqCAaQPHoBH3T2fxeWZCOyGh3DrcNdpJfBwjw8dCvyAEBJkqJ/1H9kDTFGH6sA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/IRQ: reduce casting involved in guest action retrieval
Message-Id: <E1klaWg-0006ux-AH@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:35:14 +0000

commit a00b271677bfa6365cd0446e09a0f41017e166d3
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 4 13:17:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 4 13:17:24 2020 +0100

    x86/IRQ: reduce casting involved in guest action retrieval
    
    Introduce a helper function covering both the IRQ_GUEST check and the
    cast involved in obtaining the (correctly typed) pointer. Where possible
    add const and/or reduce variable scope.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/irq.c | 76 ++++++++++++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 45 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 0f2c491edc..3387c1b5c3 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -1042,6 +1042,11 @@ typedef struct {
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
+static irq_guest_action_t *guest_action(const struct irq_desc *desc)
+{
+    return desc->status & IRQ_GUEST ? (void *)desc->action : NULL;
+}
+
 /*
  * Stack of interrupts awaiting EOI on each CPU. These must be popped in
  * order, as only the current highest-priority pending irq can be EOIed.
@@ -1111,11 +1116,9 @@ static void irq_guest_eoi_timer_fn(void *data)
 
     spin_lock_irq(&desc->lock);
     
-    if ( !(desc->status & IRQ_GUEST) )
+    if ( !(action = guest_action(desc)) )
         goto out;
 
-    action = (irq_guest_action_t *)desc->action;
-
     ASSERT(action->ack_type != ACKTYPE_NONE);
 
     /*
@@ -1351,16 +1354,15 @@ static void flush_ready_eoi(void)
     pending_eoi_sp(peoi) = sp+1;
 }
 
-static void __set_eoi_ready(struct irq_desc *desc)
+static void __set_eoi_ready(const struct irq_desc *desc)
 {
-    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    irq_guest_action_t *action = guest_action(desc);
     struct pending_eoi *peoi = this_cpu(pending_eoi);
     int                 irq, sp;
 
     irq = desc - irq_desc;
 
-    if ( !(desc->status & IRQ_GUEST) ||
-         (action->in_flight != 0) ||
+    if ( !action || action->in_flight ||
          !cpumask_test_and_clear_cpu(smp_processor_id(),
                                      action->cpu_eoi_map) )
         return;
@@ -1400,18 +1402,11 @@ void pirq_guest_eoi(struct pirq *pirq)
 
 void desc_guest_eoi(struct irq_desc *desc, struct pirq *pirq)
 {
-    irq_guest_action_t *action;
+    irq_guest_action_t *action = guest_action(desc);
     cpumask_t           cpu_eoi_map;
 
-    if ( !(desc->status & IRQ_GUEST) )
-    {
-        spin_unlock_irq(&desc->lock);
-        return;
-    }
-
-    action = (irq_guest_action_t *)desc->action;
-
-    if ( unlikely(!test_and_clear_bool(pirq->masked)) ||
+    if ( unlikely(!action) ||
+         unlikely(!test_and_clear_bool(pirq->masked)) ||
          unlikely(--action->in_flight != 0) )
     {
         spin_unlock_irq(&desc->lock);
@@ -1510,8 +1505,8 @@ static int irq_acktype(const struct irq_desc *desc)
 
 int pirq_shared(struct domain *d, int pirq)
 {
-    struct irq_desc         *desc;
-    irq_guest_action_t *action;
+    struct irq_desc    *desc;
+    const irq_guest_action_t *action;
     unsigned long       flags;
     int                 shared;
 
@@ -1519,8 +1514,8 @@ int pirq_shared(struct domain *d, int pirq)
     if ( desc == NULL )
         return 0;
 
-    action = (irq_guest_action_t *)desc->action;
-    shared = ((desc->status & IRQ_GUEST) && (action->nr_guests > 1));
+    action = guest_action(desc);
+    shared = (action && (action->nr_guests > 1));
 
     spin_unlock_irqrestore(&desc->lock, flags);
 
@@ -1544,9 +1539,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto out;
     }
 
-    action = (irq_guest_action_t *)desc->action;
-
-    if ( !(desc->status & IRQ_GUEST) )
+    if ( !(action = guest_action(desc)) )
     {
         if ( desc->action != NULL )
         {
@@ -1659,21 +1652,18 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 static irq_guest_action_t *__pirq_guest_unbind(
     struct domain *d, struct pirq *pirq, struct irq_desc *desc)
 {
-    irq_guest_action_t *action;
+    irq_guest_action_t *action = guest_action(desc);
     cpumask_t           cpu_eoi_map;
     int                 i;
 
-    action = (irq_guest_action_t *)desc->action;
-
     if ( unlikely(action == NULL) )
     {
         dprintk(XENLOG_G_WARNING, "dom%d: pirq %d: desc->action is NULL!\n",
                 d->domain_id, pirq->pirq);
+        BUG_ON(!(desc->status & IRQ_GUEST));
         return NULL;
     }
 
-    BUG_ON(!(desc->status & IRQ_GUEST));
-
     for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ )
         continue;
     BUG_ON(i == action->nr_guests);
@@ -1793,14 +1783,12 @@ static bool pirq_guest_force_unbind(struct domain *d, struct pirq *pirq)
     desc = pirq_spin_lock_irq_desc(pirq, NULL);
     BUG_ON(desc == NULL);
 
-    if ( !(desc->status & IRQ_GUEST) )
-        goto out;
-
-    action = (irq_guest_action_t *)desc->action;
+    action = guest_action(desc);
     if ( unlikely(action == NULL) )
     {
-        dprintk(XENLOG_G_WARNING, "dom%d: pirq %d: desc->action is NULL!\n",
-            d->domain_id, pirq->pirq);
+        if ( desc->status & IRQ_GUEST )
+            dprintk(XENLOG_G_WARNING, "%pd: pirq %d: desc->action is NULL!\n",
+                    d, pirq->pirq);
         goto out;
     }
 
@@ -1827,7 +1815,7 @@ static bool pirq_guest_force_unbind(struct domain *d, struct pirq *pirq)
 
 static void do_IRQ_guest(struct irq_desc *desc, unsigned int vector)
 {
-    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
+    irq_guest_action_t *action = guest_action(desc);
     unsigned int        i;
     struct pending_eoi *peoi = this_cpu(pending_eoi);
 
@@ -2444,7 +2432,6 @@ static void dump_irqs(unsigned char key)
 {
     int i, irq, pirq;
     struct irq_desc *desc;
-    irq_guest_action_t *action;
     struct domain *d;
     const struct pirq *info;
     unsigned long flags;
@@ -2454,6 +2441,8 @@ static void dump_irqs(unsigned char key)
 
     for ( irq = 0; irq < nr_irqs; irq++ )
     {
+        const irq_guest_action_t *action;
+
         if ( !(irq & 0x1f) )
             process_pending_softirqs();
 
@@ -2473,10 +2462,9 @@ static void dump_irqs(unsigned char key)
         if ( ssid )
             printk("Z=%-25s ", ssid);
 
-        if ( desc->status & IRQ_GUEST )
+        action = guest_action(desc);
+        if ( action )
         {
-            action = (irq_guest_action_t *)desc->action;
-
             printk("in-flight=%d%c",
                    action->in_flight, action->nr_guests ? ' ' : '\n');
 
@@ -2651,17 +2639,15 @@ void fixup_irqs(const cpumask_t *mask, bool verbose)
 void fixup_eoi(void)
 {
     unsigned int irq, sp;
-    struct irq_desc *desc;
-    irq_guest_action_t *action;
     struct pending_eoi *peoi;
 
     /* Clean up cpu_eoi_map of every interrupt to exclude this CPU. */
     for ( irq = 0; irq < nr_irqs; irq++ )
     {
-        desc = irq_to_desc(irq);
-        if ( !(desc->status & IRQ_GUEST) )
+        irq_guest_action_t *action = guest_action(irq_to_desc(irq));
+
+        if ( !action )
             continue;
-        action = (irq_guest_action_t *)desc->action;
         cpumask_clear_cpu(smp_processor_id(), action->cpu_eoi_map);
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 05 16:35:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 05 Dec 2020 16:35:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.45436.80899 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWr-0005n1-OT; Sat, 05 Dec 2020 16:35:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 45436.80899; Sat, 05 Dec 2020 16:35:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1klaWr-0005ms-L9; Sat, 05 Dec 2020 16:35:25 +0000
Received: by outflank-mailman (input) for mailman id 45436;
 Sat, 05 Dec 2020 16:35:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWq-0005mi-Fb
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWq-0001X7-Es
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1klaWq-0006vv-Dq
 for xen-changelog@lists.xenproject.org; Sat, 05 Dec 2020 16:35:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LZU+XhBebNj88CzwgBCK8BW9M5hJ3uXuXFLX0jwUkYU=; b=TUhanIjbdzsgxapLavlWsWupkf
	YhUXnNaMXLt09jgCLNqIdXgV3ri5Z8pWImFBsbNhqPVI3KLpT810dxad3d3dZv8cMD2+RG1/hk+2t
	SGELg2ibORiqKrnt1axUSuC0egDCXHnQRwLGsq3Nh3KGI1XnrMKBomHJSdkA6yJxgBmY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/libs/ctrl: fix dumping of ballooned guest
Message-Id: <E1klaWq-0006vv-Dq@xenbits.xenproject.org>
Date: Sat, 05 Dec 2020 16:35:24 +0000

commit 5e666356a9d55fbd9eb5b8506088aa760e107b5b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Wed Nov 11 11:01:43 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Fri Dec 4 13:35:46 2020 +0000

    tools/libs/ctrl: fix dumping of ballooned guest
    
    A guest with memory < maxmem often can't be dumped via xl dump-core
    without an error message today:
    
    xc: info: exceeded nr_pages (262144) losing pages
    
    In case the last page of the guest isn't allocated the loop in
    xc_domain_dumpcore_via_callback() will always spit out this message,
    as the number of already dumped pages is tested before the next page
    is checked to be valid.
    
    The guest's p2m_size might be lower than expected, so this should be
    tested in order to avoid reading past the end of it.
    
    The guest might use high bits in p2m entries to flag special cases like
    foreign mappings. Entries with an MFN larger than the highest MFN of
    the host should be skipped.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/libs/ctrl/xc_core.c | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/tools/libs/ctrl/xc_core.c b/tools/libs/ctrl/xc_core.c
index e8c6fb96f9..b47ab2f6d8 100644
--- a/tools/libs/ctrl/xc_core.c
+++ b/tools/libs/ctrl/xc_core.c
@@ -439,6 +439,7 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
     unsigned long i;
     unsigned long j;
     unsigned long nr_pages;
+    unsigned long max_mfn;
 
     xc_core_memory_map_t *memory_map = NULL;
     unsigned int nr_memory_map;
@@ -577,6 +578,10 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                                    &p2m, &dinfo->p2m_size);
         if ( sts != 0 )
             goto out;
+
+        sts = xc_maximum_ram_page(xch, &max_mfn);
+        if ( sts != 0 )
+            goto out;
     }
     else
     {
@@ -818,19 +823,12 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
         {
             uint64_t gmfn;
             void *vaddr;
-            
-            if ( j >= nr_pages )
-            {
-                /*
-                 * When live dump-mode (-L option) is specified,
-                 * guest domain may increase memory.
-                 */
-                IPRINTF("exceeded nr_pages (%ld) losing pages", nr_pages);
-                goto copy_done;
-            }
 
             if ( !auto_translated_physmap )
             {
+                if ( i >= dinfo->p2m_size )
+                    break;
+
                 if ( dinfo->guest_width >= sizeof(unsigned long) )
                 {
                     if ( dinfo->guest_width == sizeof(unsigned long) )
@@ -846,6 +844,14 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                     if ( gmfn == (uint32_t)INVALID_PFN )
                        continue;
                 }
+                if ( gmfn > max_mfn )
+                    continue;
+
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
 
                 p2m_array[j].pfn = i;
                 p2m_array[j].gmfn = gmfn;
@@ -855,6 +861,12 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
                 if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
                     continue;
 
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
+
                 gmfn = i;
                 pfn_array[j] = i;
             }
@@ -879,7 +891,15 @@ xc_domain_dumpcore_via_callback(xc_interface *xch,
         }
     }
 
-copy_done:
+    if ( j > nr_pages )
+    {
+        /*
+         * When live dump-mode (-L option) is specified,
+         * guest domain may increase memory.
+         */
+        IPRINTF("exceeded nr_pages (%ld) losing %ld pages", nr_pages, j - nr_pages);
+    }
+
     sts = dump_rtn(xch, args, dump_mem_start, dump_mem - dump_mem_start);
     if ( sts != 0 )
         goto out;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 14:00:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 14:00:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46612.82704 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3f-0001uW-L4; Mon, 07 Dec 2020 14:00:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46612.82704; Mon, 07 Dec 2020 14:00:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3f-0001uO-Hv; Mon, 07 Dec 2020 14:00:07 +0000
Received: by outflank-mailman (input) for mailman id 46612;
 Mon, 07 Dec 2020 14:00:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3d-0001qX-TC
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3d-0001c4-QV
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3d-0001nB-P2
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KK/lXEImqAv4m8qrKQP+RlbCvRQXLKv47nhRcn6B0hg=; b=ygRlw39adNWVi8pvR5kH4nTCNo
	jRrhVfvBajMkZ7WKBokypCbHiFFKer4mc+wfrpx1E1qGprhq6D+RTbavVpgVX5GwVtdkP6raze617
	Zl83GdNS7pBHhWWdCCHcPwIKKo7aIqD/ILQOoHcRtnHHpigTZia/j1FMtpwg3RbFqkuc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/IRQ: make max number of guests for a shared IRQ configurable
Message-Id: <E1kmH3d-0001nB-P2@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 14:00:05 +0000

commit e373bc1bdc593564e15d11a7a50f74968907ee5f
Author:     Igor Druzhinin <igor.druzhinin@citrix.com>
AuthorDate: Mon Dec 7 14:49:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:49:30 2020 +0100

    x86/IRQ: make max number of guests for a shared IRQ configurable
    
    ... and increase the default to 16.
    
    Current limit of 7 is too restrictive for modern systems where one GSI
    could be shared by potentially many PCI INTx sources where each of them
    corresponds to a device passed through to its own guest. Some systems do not
    apply due dilligence in swizzling INTx links in case e.g. INTA is declared as
    interrupt pin for the majority of PCI devices behind a single router,
    resulting in overuse of a GSI.
    
    Introduce a new command line option to configure that limit and dynamically
    allocate an array of the necessary size. Set the default size now to 16 which
    is higher than 7 but could later be increased even more if necessary.
    
    Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/xen-command-line.pandoc | 10 ++++++++++
 xen/arch/x86/irq.c                | 26 +++++++++++++++++++-------
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index b4a0d60c11..53e676b30f 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1641,6 +1641,16 @@ This option is ignored in **pv-shim** mode.
 ### nr_irqs (x86)
 > `= <integer>`
 
+### irq-max-guests (x86)
+> `= <integer>`
+
+> Default: `16`
+
+Maximum number of guests any individual IRQ could be shared between,
+i.e. a limit on the number of guests it is possible to start each having
+assigned a device sharing a common interrupt line.  Accepts values between
+1 and 255.
+
 ### numa (x86)
 > `= on | off | fake=<integer> | noacpi`
 
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 3387c1b5c3..1a60160916 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -42,6 +42,10 @@ integer_param("nr_irqs", nr_irqs);
 int __read_mostly opt_irq_vector_map = OPT_IRQ_VECTOR_MAP_DEFAULT;
 custom_param("irq_vector_map", parse_irq_vector_map_param);
 
+/* Max number of guests IRQ could be shared with */
+static unsigned char __read_mostly irq_max_guests;
+integer_param("irq-max-guests", irq_max_guests);
+
 vmask_t global_used_vector_map;
 
 struct irq_desc __read_mostly *irq_desc = NULL;
@@ -435,6 +439,9 @@ int __init init_irq_data(void)
     for ( ; irq < nr_irqs; irq++ )
         irq_to_desc(irq)->irq = irq;
 
+    if ( !irq_max_guests )
+        irq_max_guests = 16;
+
 #ifdef CONFIG_PV
     /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
     set_bit(LEGACY_SYSCALL_VECTOR, used_vectors);
@@ -1028,7 +1035,6 @@ int __init setup_irq(unsigned int irq, unsigned int irqflags,
  * HANDLING OF GUEST-BOUND PHYSICAL IRQS
  */
 
-#define IRQ_MAX_GUESTS 7
 typedef struct {
     u8 nr_guests;
     u8 in_flight;
@@ -1039,7 +1045,7 @@ typedef struct {
 #define ACKTYPE_EOI    2     /* EOI on the CPU that was interrupted  */
     cpumask_var_t cpu_eoi_map; /* CPUs that need to EOI this interrupt */
     struct timer eoi_timer;
-    struct domain *guest[IRQ_MAX_GUESTS];
+    struct domain *guest[];
 } irq_guest_action_t;
 
 static irq_guest_action_t *guest_action(const struct irq_desc *desc)
@@ -1553,7 +1559,8 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         if ( newaction == NULL )
         {
             spin_unlock_irq(&desc->lock);
-            if ( (newaction = xmalloc(irq_guest_action_t)) != NULL &&
+            if ( (newaction = xmalloc_flex_struct(irq_guest_action_t, guest,
+                                                  irq_max_guests)) != NULL &&
                  zalloc_cpumask_var(&newaction->cpu_eoi_map) )
                 goto retry;
             xfree(newaction);
@@ -1622,11 +1629,12 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto retry;
     }
 
-    if ( action->nr_guests == IRQ_MAX_GUESTS )
+    if ( action->nr_guests == irq_max_guests )
     {
-        printk(XENLOG_G_INFO "Cannot bind IRQ%d to dom%d. "
-               "Already at max share.\n",
-               pirq->pirq, v->domain->domain_id);
+        printk(XENLOG_G_INFO
+               "Cannot bind IRQ%d to %pd: already at max share %u"
+               " (increase with irq-max-guests= option)\n",
+               pirq->pirq, v->domain, irq_max_guests);
         rc = -EBUSY;
         goto unlock_out;
     }
@@ -2510,6 +2518,10 @@ static void dump_irqs(unsigned char key)
 
 static int __init setup_dump_irqs(void)
 {
+    /* In lieu of being able to live in init_irq_data(). */
+    BUILD_BUG_ON(sizeof(irq_max_guests) >
+                 sizeof_field(irq_guest_action_t, nr_guests));
+
     register_keyhandler('i', dump_irqs, "dump interrupt bindings", 1);
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 14:00:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 14:00:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46613.82708 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3p-0001vK-ML; Mon, 07 Dec 2020 14:00:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46613.82708; Mon, 07 Dec 2020 14:00:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3p-0001vD-Ja; Mon, 07 Dec 2020 14:00:17 +0000
Received: by outflank-mailman (input) for mailman id 46613;
 Mon, 07 Dec 2020 14:00:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3o-0001v5-0D
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3n-0001c7-VB
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3n-0001oP-TE
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0zVbu81spcPVGRvxPMW3zb+0mMkfhXUX40ANUxYAPGA=; b=QJF/2QC9Ufpnwd9Fsy0LQ2LOl7
	sAovkOArA9NbOhKXlOt4PczDy66fQfhQCLlbA4RnYRygW6Xqg2X1LFV8CVPj2vTAyWea6TqWvLt7h
	ny8N4uzphTkDb1Cctyio538k2MLUHVT741Q01Eln23q6S7u0y517vwQiXq/lLNhMHhKA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/IRQ: allocate guest array of max size only for shareable IRQs
Message-Id: <E1kmH3n-0001oP-TE@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 14:00:15 +0000

commit b7c333016e3d6adf38e80b4e6b121950da092405
Author:     Igor Druzhinin <igor.druzhinin@citrix.com>
AuthorDate: Mon Dec 7 14:52:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:52:35 2020 +0100

    x86/IRQ: allocate guest array of max size only for shareable IRQs
    
    ... and increase default "irq-max-guests" to 32.
    
    It's not necessary to have an array of a size more than 1 for non-shareable
    IRQs and it might impact scalability in case of high "irq-max-guests"
    values being used - every IRQ in the system including MSIs would be
    supplied with an array of that size.
    
    Since it's now less impactful to use higher "irq-max-guests" value - bump
    the default to 32. That should give more headroom for future systems.
    
    Requested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/xen-command-line.pandoc | 2 +-
 xen/arch/x86/irq.c                | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index 53e676b30f..f7db2b64aa 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1644,7 +1644,7 @@ This option is ignored in **pv-shim** mode.
 ### irq-max-guests (x86)
 > `= <integer>`
 
-> Default: `16`
+> Default: `32`
 
 Maximum number of guests any individual IRQ could be shared between,
 i.e. a limit on the number of guests it is possible to start each having
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 1a60160916..f82c93dfdc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -440,7 +440,7 @@ int __init init_irq_data(void)
         irq_to_desc(irq)->irq = irq;
 
     if ( !irq_max_guests )
-        irq_max_guests = 16;
+        irq_max_guests = 32;
 
 #ifdef CONFIG_PV
     /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
@@ -1532,6 +1532,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 {
     struct irq_desc         *desc;
     irq_guest_action_t *action, *newaction = NULL;
+    unsigned int        max_nr_guests = will_share ? irq_max_guests : 1;
     int                 rc = 0;
 
     WARN_ON(!spin_is_locked(&v->domain->event_lock));
@@ -1560,7 +1561,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         {
             spin_unlock_irq(&desc->lock);
             if ( (newaction = xmalloc_flex_struct(irq_guest_action_t, guest,
-                                                  irq_max_guests)) != NULL &&
+                                                  max_nr_guests)) != NULL &&
                  zalloc_cpumask_var(&newaction->cpu_eoi_map) )
                 goto retry;
             xfree(newaction);
@@ -1629,7 +1630,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto retry;
     }
 
-    if ( action->nr_guests == irq_max_guests )
+    if ( action->nr_guests >= max_nr_guests )
     {
         printk(XENLOG_G_INFO
                "Cannot bind IRQ%d to %pd: already at max share %u"
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 14:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 14:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46614.82712 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3z-0001x5-OC; Mon, 07 Dec 2020 14:00:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46614.82712; Mon, 07 Dec 2020 14:00:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH3z-0001wx-LD; Mon, 07 Dec 2020 14:00:27 +0000
Received: by outflank-mailman (input) for mailman id 46614;
 Mon, 07 Dec 2020 14:00:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3y-0001wK-4v
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3y-0001cF-2W
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH3y-0001p0-1T
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yR+ObYri0lZItXj9s2vVDxzJjWcPAEDZ2hKpKxOCPO8=; b=qP/owkpi5VPtIBf4t7eGbypuN/
	MJqM3PzQceufloOZ07BVrbI/pFe/PDeWJT2ttGS2yOWNbv4stxDvPyXVROwueUQgaIHq4nBjCP1Z0
	+4DsrzrzSn/tUVM0iWtcwaCtG+NtNPxg4M6fDChZ0F/vkYY017vm8L0yQFupsrDaVFtU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/vIO-APIC: make use of xmalloc_flex_struct()
Message-Id: <E1kmH3y-0001p0-1T@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 14:00:26 +0000

commit d218fb11884346bb079fa2226ab8786a7bfeee16
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Mon Dec 7 14:53:20 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:53:20 2020 +0100

    x86/vIO-APIC: make use of xmalloc_flex_struct()
    
    ... instead of effectively open-coding it in a type-unsafe way. Drop
    hvm_vioapic_size() altogether, folding the other use in a memset()
    invocation into the subsequent loop.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/vioapic.c        | 7 ++++---
 xen/include/asm-x86/hvm/vioapic.h | 1 -
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index e64abee7a9..7c462a44d4 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -622,9 +622,9 @@ void vioapic_reset(struct domain *d)
         unsigned int nr_pins = vioapic->nr_pins, base_gsi = vioapic->base_gsi;
         unsigned int pin;
 
-        memset(vioapic, 0, hvm_vioapic_size(nr_pins));
+        memset(vioapic, 0, offsetof(typeof(*vioapic), redirtbl));
         for ( pin = 0; pin < nr_pins; pin++ )
-            vioapic->redirtbl[pin].fields.mask = 1;
+            vioapic->redirtbl[pin] = (union vioapic_redir_entry){ .fields.mask = 1 };
 
         if ( !is_hardware_domain(d) )
         {
@@ -685,7 +685,8 @@ int vioapic_init(struct domain *d)
         }
 
         if ( (domain_vioapic(d, i) =
-              xmalloc_bytes(hvm_vioapic_size(nr_pins))) == NULL )
+              xmalloc_flex_struct(struct hvm_vioapic, redirtbl,
+                                  nr_pins)) == NULL )
         {
             vioapic_free(d, nr_vioapics);
             return -ENOMEM;
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index d6f4e12d54..36b64d20d6 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -56,7 +56,6 @@ struct hvm_vioapic {
     };
 };
 
-#define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
 #define domain_vioapic(d, i) ((d)->arch.hvm.vioapic[i])
 #define vioapic_domain(v) ((v)->domain)
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 14:00:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 14:00:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46615.82716 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH49-0001yY-Pr; Mon, 07 Dec 2020 14:00:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46615.82716; Mon, 07 Dec 2020 14:00:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH49-0001yQ-Ml; Mon, 07 Dec 2020 14:00:37 +0000
Received: by outflank-mailman (input) for mailman id 46615;
 Mon, 07 Dec 2020 14:00:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH48-0001yI-6n
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH48-0001cV-5x
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH48-0001ps-52
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=o+okGVIT9LZnUFlUQ3mMUwwyppdS4Gp8lvaBD4E34NI=; b=NB11xyxhxeOju212/hsjYKq4LE
	Q/PrXKgvQc+sAQtArU9Z8wQffdX1srH499EIjn5ZsPrMvr7a72Pw0dGkr4QKDVKbV0jHhGR4b+pvS
	XaH1NZgm9mOd7Z81iPEi19yIzo1jqRD9su68G3NUCrQlxw2TE7SUrTXy0L/jVN4bOKwQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/vPMU: make use of xmalloc_flex_struct()
Message-Id: <E1kmH48-0001ps-52@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 14:00:36 +0000

commit 826a6dd030fe7d2a62b019e7d6e51ab79227f4aa
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Mon Dec 7 14:54:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:54:08 2020 +0100

    x86/vPMU: make use of xmalloc_flex_struct()
    
    ... instead of effectively open-coding it in a type-unsafe way. Drop the
    regs_sz variable altogether, replacing other uses suitably.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/cpu/vpmu_amd.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu_amd.c b/xen/arch/x86/cpu/vpmu_amd.c
index eba47cd2a0..38972089ab 100644
--- a/xen/arch/x86/cpu/vpmu_amd.c
+++ b/xen/arch/x86/cpu/vpmu_amd.c
@@ -44,9 +44,6 @@ static const u32 __read_mostly *counters;
 static const u32 __read_mostly *ctrls;
 static bool_t __read_mostly k7_counters_mirrored;
 
-/* Total size of PMU registers block (copied to/from PV(H) guest) */
-static unsigned int __read_mostly regs_sz;
-
 #define F10H_NUM_COUNTERS   4
 #define F15H_NUM_COUNTERS   6
 #define MAX_NUM_COUNTERS    F15H_NUM_COUNTERS
@@ -156,12 +153,9 @@ static inline u32 get_fam15h_addr(u32 addr)
 
 static void amd_vpmu_init_regs(struct xen_pmu_amd_ctxt *ctxt)
 {
-    unsigned i;
-    uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls);
-
-    memset(&ctxt->regs[0], 0, regs_sz);
-    for ( i = 0; i < num_counters; i++ )
-        ctrl_regs[i] = ctrl_rsvd[i];
+    memset(&ctxt->regs[0], 0, num_counters * sizeof(ctxt->regs[0]));
+    memcpy(&ctxt->regs[num_counters], &ctrl_rsvd[0],
+           num_counters * sizeof(ctxt->regs[0]));
 }
 
 static void amd_vpmu_set_msr_bitmap(struct vcpu *v)
@@ -242,7 +236,8 @@ static int amd_vpmu_load(struct vcpu *v, bool_t from_guest)
         ctxt = vpmu->context;
         ctrl_regs = vpmu_reg_pointer(ctxt, ctrls);
 
-        memcpy(&ctxt->regs[0], &guest_ctxt->regs[0], regs_sz);
+        memcpy(&ctxt->regs[0], &guest_ctxt->regs[0],
+               2 * num_counters * sizeof(ctxt->regs[0]));
 
         for ( i = 0; i < num_counters; i++ )
         {
@@ -316,7 +311,8 @@ static int amd_vpmu_save(struct vcpu *v,  bool_t to_guest)
         ASSERT(!has_vlapic(v->domain));
         ctxt = vpmu->context;
         guest_ctxt = &vpmu->xenpmu_data->pmu.c.amd;
-        memcpy(&guest_ctxt->regs[0], &ctxt->regs[0], regs_sz);
+        memcpy(&guest_ctxt->regs[0], &ctxt->regs[0],
+               2 * num_counters * sizeof(ctxt->regs[0]));
     }
 
     return 1;
@@ -508,7 +504,8 @@ int svm_vpmu_initialise(struct vcpu *v)
     if ( !counters )
         return -EINVAL;
 
-    ctxt = xmalloc_bytes(sizeof(*ctxt) + regs_sz);
+    ctxt = xmalloc_flex_struct(struct xen_pmu_amd_ctxt, regs,
+                               2 * num_counters);
     if ( !ctxt )
     {
         printk(XENLOG_G_WARNING "Insufficient memory for PMU, "
@@ -565,8 +562,6 @@ static int __init common_init(void)
         ctrl_rsvd[i] &= CTRL_RSVD_MASK;
     }
 
-    regs_sz = 2 * sizeof(uint64_t) * num_counters;
-
     return 0;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 14:00:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 14:00:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46616.82722 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH4J-000205-SP; Mon, 07 Dec 2020 14:00:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46616.82722; Mon, 07 Dec 2020 14:00:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmH4J-0001zx-OO; Mon, 07 Dec 2020 14:00:47 +0000
Received: by outflank-mailman (input) for mailman id 46616;
 Mon, 07 Dec 2020 14:00:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH4I-0001zo-Bc
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH4I-0001dH-A1
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmH4I-0001qo-8u
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 14:00:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=3ZbteyI69Ruzs4e9Bty2jX+X7UpbeeufpSTx1SZybGE=; b=bldCIrNF6rwVfgTxCDt8w9AD+d
	v3ilQYKynjqaVFClP5lk8OHxA+3c6AzmoGAIH9b4jmYFzB3tYzLy8YJXeZnE5Fhi+A8lPUDIhJmCA
	bPVF5ExO4bMKw6s3mDwQfyzA9EenXouEeag/zdwSc87Mb2KiP9XyjBX9p5bVkocCLDj4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/vmap: handle superpages in vmap_to_mfn()
Message-Id: <E1kmH4I-0001qo-8u@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 14:00:46 +0000

commit 3ec53aa79905edc3891b8267123d88a221553370
Author:     Hongyan Xia <hongyxia@amazon.com>
AuthorDate: Mon Dec 7 14:54:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:54:44 2020 +0100

    x86/vmap: handle superpages in vmap_to_mfn()
    
    There is simply no guarantee that vmap won't return superpages to the
    caller. It can happen if the list of MFNs are contiguous, or we simply
    have a large granularity. Although rare, if such things do happen, we
    will simply hit BUG_ON() and crash.
    
    Introduce xen_map_to_mfn() to translate any mapped Xen address to mfn
    regardless of page size, and wrap vmap_to_mfn() around it.
    
    Signed-off-by: Hongyan Xia <hongyxia@amazon.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/mm.c          | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/page.h |  2 +-
 xen/include/xen/mm.h       |  3 +++
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 5a50339284..723cc1070f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5194,6 +5194,62 @@ l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
         }                                          \
     } while ( false )
 
+/* Translate mapped Xen address to MFN. */
+mfn_t xen_map_to_mfn(unsigned long va)
+{
+#define CHECK_MAPPED(cond)          \
+    do {                            \
+        if ( !(cond) )              \
+        {                           \
+            ASSERT_UNREACHABLE();   \
+            ret = INVALID_MFN;      \
+            goto out;               \
+        }                           \
+    } while ( false )
+
+    bool locking = system_state > SYS_STATE_boot;
+    unsigned int l2_offset = l2_table_offset(va);
+    unsigned int l1_offset = l1_table_offset(va);
+    const l3_pgentry_t *pl3e = virt_to_xen_l3e(va);
+    const l2_pgentry_t *pl2e = NULL;
+    const l1_pgentry_t *pl1e = NULL;
+    struct page_info *l3page;
+    mfn_t ret;
+
+    L3T_INIT(l3page);
+    CHECK_MAPPED(pl3e);
+    l3page = virt_to_page(pl3e);
+    L3T_LOCK(l3page);
+
+    CHECK_MAPPED(l3e_get_flags(*pl3e) & _PAGE_PRESENT);
+    if ( l3e_get_flags(*pl3e) & _PAGE_PSE )
+    {
+        ret = mfn_add(l3e_get_mfn(*pl3e),
+                      (l2_offset << PAGETABLE_ORDER) + l1_offset);
+        goto out;
+    }
+
+    pl2e = map_l2t_from_l3e(*pl3e) + l2_offset;
+    CHECK_MAPPED(l2e_get_flags(*pl2e) & _PAGE_PRESENT);
+    if ( l2e_get_flags(*pl2e) & _PAGE_PSE )
+    {
+        ret = mfn_add(l2e_get_mfn(*pl2e), l1_offset);
+        goto out;
+    }
+
+    pl1e = map_l1t_from_l2e(*pl2e) + l1_offset;
+    CHECK_MAPPED(l1e_get_flags(*pl1e) & _PAGE_PRESENT);
+    ret = l1e_get_mfn(*pl1e);
+
+#undef CHECK_MAPPED
+ out:
+    L3T_UNLOCK(l3page);
+    unmap_domain_page(pl1e);
+    unmap_domain_page(pl2e);
+    unmap_domain_page(pl3e);
+    return ret;
+}
+
 int map_pages_to_xen(
     unsigned long virt,
     mfn_t mfn,
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 7a771baf7c..082c14a662 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -291,7 +291,7 @@ void copy_page_sse2(void *, const void *);
 #define pfn_to_paddr(pfn)   __pfn_to_paddr(pfn)
 #define paddr_to_pfn(pa)    __paddr_to_pfn(pa)
 #define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
-#define vmap_to_mfn(va)     l1e_get_mfn(*virt_to_xen_l1e((unsigned long)(va)))
+#define vmap_to_mfn(va)     xen_map_to_mfn((unsigned long)(va))
 #define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
 
 #endif /* !defined(__ASSEMBLY__) */
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index f7975b2df0..85a8df9948 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -184,6 +184,9 @@ int map_pages_to_xen(
 /* Alter the permissions of a range of Xen virtual address space. */
 int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int flags);
 int destroy_xen_mappings(unsigned long v, unsigned long e);
+/* Retrieve the MFN mapped by VA in Xen virtual address space. */
+mfn_t xen_map_to_mfn(unsigned long va);
+
 /*
  * Create only non-leaf page table entries for the
  * page range in Xen virtual address space.
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 15:22:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 15:22:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46700.82782 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIL0-00024F-1i; Mon, 07 Dec 2020 15:22:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46700.82782; Mon, 07 Dec 2020 15:22:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIKz-000247-Uk; Mon, 07 Dec 2020 15:22:05 +0000
Received: by outflank-mailman (input) for mailman id 46700;
 Mon, 07 Dec 2020 15:22:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIKz-000241-GH
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIKz-0003Gv-D6
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIKz-0007RD-BB
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bvmHF0dgKVwNw2AR7FIZSRle0XPSHJaLL3jxfjp5tlA=; b=b8lWIT33QZT/Dq4AL8f5tudpG7
	eBnwAaD13KxldMhUImXhK0EWGl4LUojUR5jIrwXBWKp1uztOi4piBSm2zKbIOZpyDPWvoQ61MLuyc
	pKEzYfOhIfQvPN/9PgqAg824c3ZCvo6Bm5idobUg9JDEwDdSDCTqLQeF+ugpzePlnaC0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: switch cpupool id to unsigned
Message-Id: <E1kmIKz-0007RD-BB@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 15:22:05 +0000

commit 30d430b2126697dda0bd53d19fe267fb4d30e9b8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:17:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:17:50 2020 +0100

    xen/cpupool: switch cpupool id to unsigned
    
    The cpupool id is an unsigned value in the public interface header, so
    there is no reason why it is a signed value in struct cpupool.
    
    Switch it to unsigned int.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c    |  2 +-
 xen/common/sched/cpupool.c | 48 +++++++++++++++++++++++-----------------------
 xen/common/sched/private.h |  8 ++++----
 xen/include/xen/sched.h    |  4 ++--
 4 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index f8c81592af..6063f6d9ea 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -757,7 +757,7 @@ void sched_destroy_vcpu(struct vcpu *v)
     }
 }
 
-int sched_init_domain(struct domain *d, int poolid)
+int sched_init_domain(struct domain *d, unsigned int poolid)
 {
     void *sdom;
     int ret;
diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 84f326ea63..01fa71dd00 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -187,7 +187,7 @@ static struct cpupool *alloc_cpupool_struct(void)
  * the searched id is returned
  * returns NULL if not found.
  */
-static struct cpupool *__cpupool_find_by_id(int id, bool exact)
+static struct cpupool *__cpupool_find_by_id(unsigned int id, bool exact)
 {
     struct cpupool **q;
 
@@ -200,12 +200,12 @@ static struct cpupool *__cpupool_find_by_id(int id, bool exact)
     return (!exact || (*q == NULL) || ((*q)->cpupool_id == id)) ? *q : NULL;
 }
 
-static struct cpupool *cpupool_find_by_id(int poolid)
+static struct cpupool *cpupool_find_by_id(unsigned int poolid)
 {
     return __cpupool_find_by_id(poolid, true);
 }
 
-static struct cpupool *__cpupool_get_by_id(int poolid, bool exact)
+static struct cpupool *__cpupool_get_by_id(unsigned int poolid, bool exact)
 {
     struct cpupool *c;
     spin_lock(&cpupool_lock);
@@ -216,12 +216,12 @@ static struct cpupool *__cpupool_get_by_id(int poolid, bool exact)
     return c;
 }
 
-struct cpupool *cpupool_get_by_id(int poolid)
+struct cpupool *cpupool_get_by_id(unsigned int poolid)
 {
     return __cpupool_get_by_id(poolid, true);
 }
 
-static struct cpupool *cpupool_get_next_by_id(int poolid)
+static struct cpupool *cpupool_get_next_by_id(unsigned int poolid)
 {
     return __cpupool_get_by_id(poolid, false);
 }
@@ -243,11 +243,11 @@ void cpupool_put(struct cpupool *pool)
  * - unknown scheduler
  */
 static struct cpupool *cpupool_create(
-    int poolid, unsigned int sched_id, int *perr)
+    unsigned int poolid, unsigned int sched_id, int *perr)
 {
     struct cpupool *c;
     struct cpupool **q;
-    int last = 0;
+    unsigned int last = 0;
 
     *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
@@ -256,7 +256,7 @@ static struct cpupool *cpupool_create(
     /* One reference for caller, one reference for cpupool_destroy(). */
     atomic_set(&c->refcnt, 2);
 
-    debugtrace_printk("cpupool_create(pool=%d,sched=%u)\n", poolid, sched_id);
+    debugtrace_printk("cpupool_create(pool=%u,sched=%u)\n", poolid, sched_id);
 
     spin_lock(&cpupool_lock);
 
@@ -295,7 +295,7 @@ static struct cpupool *cpupool_create(
 
     spin_unlock(&cpupool_lock);
 
-    debugtrace_printk("Created cpupool %d with scheduler %s (%s)\n",
+    debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
                       c->cpupool_id, c->sched->name, c->sched->opt_name);
 
     *perr = 0;
@@ -337,7 +337,7 @@ static int cpupool_destroy(struct cpupool *c)
 
     cpupool_put(c);
 
-    debugtrace_printk("cpupool_destroy(pool=%d)\n", c->cpupool_id);
+    debugtrace_printk("cpupool_destroy(pool=%u)\n", c->cpupool_id);
     return 0;
 }
 
@@ -521,7 +521,7 @@ static long cpupool_unassign_cpu_helper(void *info)
     struct cpupool *c = info;
     long ret;
 
-    debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d)\n",
+    debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d)\n",
                       cpupool_cpu_moving->cpupool_id, cpupool_moving_cpu);
     spin_lock(&cpupool_lock);
 
@@ -551,7 +551,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
     int ret;
     unsigned int master_cpu;
 
-    debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d)\n",
+    debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d)\n",
                       c->cpupool_id, cpu);
 
     if ( !cpu_online(cpu) )
@@ -561,7 +561,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
     ret = cpupool_unassign_cpu_start(c, master_cpu);
     if ( ret )
     {
-        debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d) ret %d\n",
+        debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d) ret %d\n",
                           c->cpupool_id, cpu, ret);
         return ret;
     }
@@ -582,7 +582,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
  * - pool does not exist
  * - no cpu assigned to pool
  */
-int cpupool_add_domain(struct domain *d, int poolid)
+int cpupool_add_domain(struct domain *d, unsigned int poolid)
 {
     struct cpupool *c;
     int rc;
@@ -604,7 +604,7 @@ int cpupool_add_domain(struct domain *d, int poolid)
         rc = 0;
     }
     spin_unlock(&cpupool_lock);
-    debugtrace_printk("cpupool_add_domain(dom=%d,pool=%d) n_dom %d rc %d\n",
+    debugtrace_printk("cpupool_add_domain(dom=%d,pool=%u) n_dom %d rc %d\n",
                       d->domain_id, poolid, n_dom, rc);
     return rc;
 }
@@ -614,7 +614,7 @@ int cpupool_add_domain(struct domain *d, int poolid)
  */
 void cpupool_rm_domain(struct domain *d)
 {
-    int cpupool_id;
+    unsigned int cpupool_id;
     int n_dom;
 
     if ( d->cpupool == NULL )
@@ -625,7 +625,7 @@ void cpupool_rm_domain(struct domain *d)
     n_dom = d->cpupool->n_dom;
     d->cpupool = NULL;
     spin_unlock(&cpupool_lock);
-    debugtrace_printk("cpupool_rm_domain(dom=%d,pool=%d) n_dom %d\n",
+    debugtrace_printk("cpupool_rm_domain(dom=%d,pool=%u) n_dom %d\n",
                       d->domain_id, cpupool_id, n_dom);
     return;
 }
@@ -767,7 +767,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
     case XEN_SYSCTL_CPUPOOL_OP_CREATE:
     {
-        int poolid;
+        unsigned int poolid;
 
         poolid = (op->cpupool_id == XEN_SYSCTL_CPUPOOL_PAR_ANY) ?
             CPUPOOLID_NONE: op->cpupool_id;
@@ -811,7 +811,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
         const cpumask_t *cpus;
 
         cpu = op->cpu;
-        debugtrace_printk("cpupool_assign_cpu(pool=%d,cpu=%d)\n",
+        debugtrace_printk("cpupool_assign_cpu(pool=%u,cpu=%u)\n",
                           op->cpupool_id, cpu);
 
         spin_lock(&cpupool_lock);
@@ -844,7 +844,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
     addcpu_out:
         spin_unlock(&cpupool_lock);
-        debugtrace_printk("cpupool_assign_cpu(pool=%d,cpu=%d) ret %d\n",
+        debugtrace_printk("cpupool_assign_cpu(pool=%u,cpu=%u) ret %d\n",
                           op->cpupool_id, cpu, ret);
 
     }
@@ -885,7 +885,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
             rcu_unlock_domain(d);
             break;
         }
-        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%d\n",
+        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%u\n",
                           d->domain_id, op->cpupool_id);
         ret = -ENOENT;
         spin_lock(&cpupool_lock);
@@ -895,7 +895,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
             ret = cpupool_move_domain_locked(d, c);
 
         spin_unlock(&cpupool_lock);
-        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%d ret %d\n",
+        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%u ret %d\n",
                           d->domain_id, op->cpupool_id, ret);
         rcu_unlock_domain(d);
     }
@@ -916,7 +916,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
     return ret;
 }
 
-int cpupool_get_id(const struct domain *d)
+unsigned int cpupool_get_id(const struct domain *d)
 {
     return d->cpupool ? d->cpupool->cpupool_id : CPUPOOLID_NONE;
 }
@@ -946,7 +946,7 @@ void dump_runq(unsigned char key)
 
     for_each_cpupool(c)
     {
-        printk("Cpupool %d:\n", (*c)->cpupool_id);
+        printk("Cpupool %u:\n", (*c)->cpupool_id);
         printk("Cpus: %*pbl\n", CPUMASK_PR((*c)->cpu_valid));
         sched_gran_print((*c)->gran, cpupool_get_granularity(*c));
         schedule_dump(*c);
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index 685992cab9..e69d9be1e8 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -505,8 +505,8 @@ static inline void sched_unit_unpause(const struct sched_unit *unit)
 
 struct cpupool
 {
-    int              cpupool_id;
-#define CPUPOOLID_NONE    (-1)
+    unsigned int     cpupool_id;
+#define CPUPOOLID_NONE    (~0U)
     unsigned int     n_dom;
     cpumask_var_t    cpu_valid;      /* all cpus assigned to pool */
     cpumask_var_t    res_valid;      /* all scheduling resources of pool */
@@ -601,9 +601,9 @@ int cpu_disable_scheduler(unsigned int cpu);
 int schedule_cpu_add(unsigned int cpu, struct cpupool *c);
 int schedule_cpu_rm(unsigned int cpu);
 int sched_move_domain(struct domain *d, struct cpupool *c);
-struct cpupool *cpupool_get_by_id(int poolid);
+struct cpupool *cpupool_get_by_id(unsigned int poolid);
 void cpupool_put(struct cpupool *pool);
-int cpupool_add_domain(struct domain *d, int poolid);
+int cpupool_add_domain(struct domain *d, unsigned int poolid);
 void cpupool_rm_domain(struct domain *d);
 
 #endif /* __XEN_SCHED_IF_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 4c380fd4b2..31abbe7a99 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -693,7 +693,7 @@ void noreturn asm_domain_crash_synchronous(unsigned long addr);
 void scheduler_init(void);
 int  sched_init_vcpu(struct vcpu *v);
 void sched_destroy_vcpu(struct vcpu *v);
-int  sched_init_domain(struct domain *d, int poolid);
+int  sched_init_domain(struct domain *d, unsigned int poolid);
 void sched_destroy_domain(struct domain *d);
 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
 long sched_adjust_global(struct xen_sysctl_scheduler_op *);
@@ -1091,7 +1091,7 @@ static always_inline bool is_cpufreq_controller(const struct domain *d)
 
 int cpupool_move_domain(struct domain *d, struct cpupool *c);
 int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op);
-int cpupool_get_id(const struct domain *d);
+unsigned int cpupool_get_id(const struct domain *d);
 const cpumask_t *cpupool_valid_cpus(const struct cpupool *pool);
 extern void dump_runq(unsigned char key);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 15:22:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 15:22:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46702.82785 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmILB-000269-4V; Mon, 07 Dec 2020 15:22:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46702.82785; Mon, 07 Dec 2020 15:22:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmILB-000262-1V; Mon, 07 Dec 2020 15:22:17 +0000
Received: by outflank-mailman (input) for mailman id 46702;
 Mon, 07 Dec 2020 15:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIL9-00025h-JI
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIL9-0003H1-I3
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIL9-0007Rs-Fc
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LT8QeJwE/3ANRPEEJx3XYRn1p0nwXTvLkCiQq5xHrH8=; b=h273Q0Ufcrcpv2wAU+rt0aMHZS
	ri1BeXqDC9NS3D6HMMRye9dU2j6e6p7+xqKyv+d83kgC5P6VCFRk6bopz1GhCe8v1BxThnWPtAxH8
	aHvJoqQI6P1RrDdmRJSbcL2ljIv7fSFMRElRMwV1Jy4QKlB+UhrX4wFD8m5WPv+l7HXA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: switch cpupool list to normal list interface
Message-Id: <E1kmIL9-0007Rs-Fc@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 15:22:15 +0000

commit d5ce1f6791342cf88aa2f5be500146820e6506ac
Author:     From: Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:18:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:18:47 2020 +0100

    xen/cpupool: switch cpupool list to normal list interface
    
    Instead of open coding something like a linked list just use the
    available functionality from list.h.
    
    The allocation of a new cpupool id is not aware of a possible wrap.
    Fix that. We don't, however, consider the case of extremely many pools
    (beyond 4 billion) as something which needs explicitly handling right
    now. First and foremost there would need to be systems with 4 billion
    CPUs to make this many pools a sensible thing to have.
    
    While adding the required new include to private.h sort the includes.
    
    Signed-off-by: From: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 100 ++++++++++++++++++++++++---------------------
 xen/common/sched/private.h |   4 +-
 2 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 01fa71dd00..714cd47ae9 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -16,6 +16,7 @@
 #include <xen/init.h>
 #include <xen/keyhandler.h>
 #include <xen/lib.h>
+#include <xen/list.h>
 #include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
@@ -23,13 +24,10 @@
 
 #include "private.h"
 
-#define for_each_cpupool(ptr)    \
-    for ((ptr) = &cpupool_list; *(ptr) != NULL; (ptr) = &((*(ptr))->next))
-
 struct cpupool *cpupool0;                /* Initial cpupool with Dom0 */
 cpumask_t cpupool_free_cpus;             /* cpus not in any cpupool */
 
-static struct cpupool *cpupool_list;     /* linked list, sorted by poolid */
+static LIST_HEAD(cpupool_list);          /* linked list, sorted by poolid */
 
 static int cpupool_moving_cpu = -1;
 static struct cpupool *cpupool_cpu_moving = NULL;
@@ -189,15 +187,15 @@ static struct cpupool *alloc_cpupool_struct(void)
  */
 static struct cpupool *__cpupool_find_by_id(unsigned int id, bool exact)
 {
-    struct cpupool **q;
+    struct cpupool *q;
 
     ASSERT(spin_is_locked(&cpupool_lock));
 
-    for_each_cpupool(q)
-        if ( (*q)->cpupool_id >= id )
-            break;
+    list_for_each_entry(q, &cpupool_list, list)
+        if ( q->cpupool_id == id || (!exact && q->cpupool_id > id) )
+            return q;
 
-    return (!exact || (*q == NULL) || ((*q)->cpupool_id == id)) ? *q : NULL;
+    return NULL;
 }
 
 static struct cpupool *cpupool_find_by_id(unsigned int poolid)
@@ -246,8 +244,7 @@ static struct cpupool *cpupool_create(
     unsigned int poolid, unsigned int sched_id, int *perr)
 {
     struct cpupool *c;
-    struct cpupool **q;
-    unsigned int last = 0;
+    struct cpupool *q;
 
     *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
@@ -260,23 +257,42 @@ static struct cpupool *cpupool_create(
 
     spin_lock(&cpupool_lock);
 
-    for_each_cpupool(q)
+    if ( poolid != CPUPOOLID_NONE )
     {
-        last = (*q)->cpupool_id;
-        if ( (poolid != CPUPOOLID_NONE) && (last >= poolid) )
-            break;
+        q = __cpupool_find_by_id(poolid, false);
+        if ( !q )
+            list_add_tail(&c->list, &cpupool_list);
+        else
+        {
+            list_add_tail(&c->list, &q->list);
+            if ( q->cpupool_id == poolid )
+            {
+                *perr = -EEXIST;
+                goto err;
+            }
+        }
+
+        c->cpupool_id = poolid;
     }
-    if ( *q != NULL )
+    else
     {
-        if ( (*q)->cpupool_id == poolid )
+        /* Cpupool 0 is created with specified id at boot and never removed. */
+        ASSERT(!list_empty(&cpupool_list));
+
+        q = list_last_entry(&cpupool_list, struct cpupool, list);
+        /* In case of wrap search for first free id. */
+        if ( q->cpupool_id == CPUPOOLID_NONE - 1 )
         {
-            *perr = -EEXIST;
-            goto err;
+            list_for_each_entry(q, &cpupool_list, list)
+                if ( q->cpupool_id + 1 != list_next_entry(q, list)->cpupool_id )
+                    break;
         }
-        c->next = *q;
+
+        list_add(&c->list, &q->list);
+
+        c->cpupool_id = q->cpupool_id + 1;
     }
 
-    c->cpupool_id = (poolid == CPUPOOLID_NONE) ? (last + 1) : poolid;
     if ( poolid == 0 )
     {
         c->sched = scheduler_get_default();
@@ -291,8 +307,6 @@ static struct cpupool *cpupool_create(
     c->gran = opt_sched_granularity;
     c->sched_gran = sched_granularity;
 
-    *q = c;
-
     spin_unlock(&cpupool_lock);
 
     debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
@@ -302,6 +316,8 @@ static struct cpupool *cpupool_create(
     return c;
 
  err:
+    list_del(&c->list);
+
     spin_unlock(&cpupool_lock);
     free_cpupool_struct(c);
     return NULL;
@@ -312,27 +328,19 @@ static struct cpupool *cpupool_create(
  * possible failures:
  * - pool still in use
  * - cpus still assigned to pool
- * - pool not in list
  */
 static int cpupool_destroy(struct cpupool *c)
 {
-    struct cpupool **q;
-
     spin_lock(&cpupool_lock);
-    for_each_cpupool(q)
-        if ( *q == c )
-            break;
-    if ( *q != c )
-    {
-        spin_unlock(&cpupool_lock);
-        return -ENOENT;
-    }
+
     if ( (c->n_dom != 0) || cpumask_weight(c->cpu_valid) )
     {
         spin_unlock(&cpupool_lock);
         return -EBUSY;
     }
-    *q = c->next;
+
+    list_del(&c->list);
+
     spin_unlock(&cpupool_lock);
 
     cpupool_put(c);
@@ -732,17 +740,17 @@ static int cpupool_cpu_remove_prologue(unsigned int cpu)
  */
 static void cpupool_cpu_remove_forced(unsigned int cpu)
 {
-    struct cpupool **c;
+    struct cpupool *c;
     int ret;
     unsigned int master_cpu = sched_get_resource_cpu(cpu);
 
-    for_each_cpupool ( c )
+    list_for_each_entry(c, &cpupool_list, list)
     {
-        if ( cpumask_test_cpu(master_cpu, (*c)->cpu_valid) )
+        if ( cpumask_test_cpu(master_cpu, c->cpu_valid) )
         {
-            ret = cpupool_unassign_cpu_start(*c, master_cpu);
+            ret = cpupool_unassign_cpu_start(c, master_cpu);
             BUG_ON(ret);
-            ret = cpupool_unassign_cpu_finish(*c);
+            ret = cpupool_unassign_cpu_finish(c);
             BUG_ON(ret);
         }
     }
@@ -929,7 +937,7 @@ const cpumask_t *cpupool_valid_cpus(const struct cpupool *pool)
 void dump_runq(unsigned char key)
 {
     s_time_t         now = NOW();
-    struct cpupool **c;
+    struct cpupool *c;
 
     spin_lock(&cpupool_lock);
 
@@ -944,12 +952,12 @@ void dump_runq(unsigned char key)
         schedule_dump(NULL);
     }
 
-    for_each_cpupool(c)
+    list_for_each_entry(c, &cpupool_list, list)
     {
-        printk("Cpupool %u:\n", (*c)->cpupool_id);
-        printk("Cpus: %*pbl\n", CPUMASK_PR((*c)->cpu_valid));
-        sched_gran_print((*c)->gran, cpupool_get_granularity(*c));
-        schedule_dump(*c);
+        printk("Cpupool %u:\n", c->cpupool_id);
+        printk("Cpus: %*pbl\n", CPUMASK_PR(c->cpu_valid));
+        sched_gran_print(c->gran, cpupool_get_granularity(c));
+        schedule_dump(c);
     }
 
     spin_unlock(&cpupool_lock);
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index e69d9be1e8..6953cefa6e 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -8,8 +8,9 @@
 #ifndef __XEN_SCHED_IF_H__
 #define __XEN_SCHED_IF_H__
 
-#include <xen/percpu.h>
 #include <xen/err.h>
+#include <xen/list.h>
+#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 
 /* cpus currently in no cpupool */
@@ -510,6 +511,7 @@ struct cpupool
     unsigned int     n_dom;
     cpumask_var_t    cpu_valid;      /* all cpus assigned to pool */
     cpumask_var_t    res_valid;      /* all scheduling resources of pool */
+    struct list_head list;
     struct cpupool   *next;
     struct scheduler *sched;
     atomic_t         refcnt;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 15:22:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 15:22:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46705.82789 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmILL-00027f-68; Mon, 07 Dec 2020 15:22:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46705.82789; Mon, 07 Dec 2020 15:22:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmILL-00027Z-39; Mon, 07 Dec 2020 15:22:27 +0000
Received: by outflank-mailman (input) for mailman id 46705;
 Mon, 07 Dec 2020 15:22:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmILJ-00027P-Nj
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmILJ-0003HF-Mp
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmILJ-0007SZ-Kj
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:22:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=mmUchoagqpJZGvMhooEcVPxfCIN0N9caw/uklr3IIeA=; b=jIsNsFAUrpHvVcVHeBwxOHkoCY
	yubBJFBro9Vx+2Gfi8H9lt3zs8pR4ZpjqvU1Zh4iNUL/R0lugb2FdHad2lnXTkBe5oPqXXxWq+GhA
	H1hW0J7LS7dVgfwo5TPjeS3+xp2EL5SDCjNps0JX7M1O+1OGNwKUDoEAHtNmTtAahnSg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: use ERR_PTR() for returning error cause from cpupool_create()
Message-Id: <E1kmILJ-0007SZ-Kj@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 15:22:25 +0000

commit 841f660b16b7e5ab9c6100d665f276074735e04c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:19:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:19:17 2020 +0100

    xen/cpupool: use ERR_PTR() for returning error cause from cpupool_create()
    
    Instead of a pointer to an error variable as parameter just use
    ERR_PTR() to return the cause of an error in cpupool_create().
    
    This propagates to scheduler_alloc(), too.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c    | 13 ++++++-------
 xen/common/sched/cpupool.c | 38 ++++++++++++++++++++------------------
 xen/common/sched/private.h |  2 +-
 3 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 6063f6d9ea..a429fc7640 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -3233,26 +3233,25 @@ struct scheduler *scheduler_get_default(void)
     return &ops;
 }
 
-struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr)
+struct scheduler *scheduler_alloc(unsigned int sched_id)
 {
     int i;
+    int ret;
     struct scheduler *sched;
 
     for ( i = 0; i < NUM_SCHEDULERS; i++ )
         if ( schedulers[i] && schedulers[i]->sched_id == sched_id )
             goto found;
-    *perr = -ENOENT;
-    return NULL;
+    return ERR_PTR(-ENOENT);
 
  found:
-    *perr = -ENOMEM;
     if ( (sched = xmalloc(struct scheduler)) == NULL )
-        return NULL;
+        return ERR_PTR(-ENOMEM);
     memcpy(sched, schedulers[i], sizeof(*sched));
-    if ( (*perr = sched_init(sched)) != 0 )
+    if ( (ret = sched_init(sched)) != 0 )
     {
         xfree(sched);
-        sched = NULL;
+        sched = ERR_PTR(ret);
     }
 
     return sched;
diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 714cd47ae9..0db7d77219 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -240,15 +240,15 @@ void cpupool_put(struct cpupool *pool)
  * - poolid already used
  * - unknown scheduler
  */
-static struct cpupool *cpupool_create(
-    unsigned int poolid, unsigned int sched_id, int *perr)
+static struct cpupool *cpupool_create(unsigned int poolid,
+                                      unsigned int sched_id)
 {
     struct cpupool *c;
     struct cpupool *q;
+    int ret;
 
-    *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
-        return NULL;
+        return ERR_PTR(-ENOMEM);
 
     /* One reference for caller, one reference for cpupool_destroy(). */
     atomic_set(&c->refcnt, 2);
@@ -267,7 +267,7 @@ static struct cpupool *cpupool_create(
             list_add_tail(&c->list, &q->list);
             if ( q->cpupool_id == poolid )
             {
-                *perr = -EEXIST;
+                ret = -EEXIST;
                 goto err;
             }
         }
@@ -294,15 +294,15 @@ static struct cpupool *cpupool_create(
     }
 
     if ( poolid == 0 )
-    {
         c->sched = scheduler_get_default();
-    }
     else
+        c->sched = scheduler_alloc(sched_id);
+    if ( IS_ERR(c->sched) )
     {
-        c->sched = scheduler_alloc(sched_id, perr);
-        if ( c->sched == NULL )
-            goto err;
+        ret = PTR_ERR(c->sched);
+        goto err;
     }
+
     c->sched->cpupool = c;
     c->gran = opt_sched_granularity;
     c->sched_gran = sched_granularity;
@@ -312,15 +312,16 @@ static struct cpupool *cpupool_create(
     debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
                       c->cpupool_id, c->sched->name, c->sched->opt_name);
 
-    *perr = 0;
     return c;
 
  err:
     list_del(&c->list);
 
     spin_unlock(&cpupool_lock);
+
     free_cpupool_struct(c);
-    return NULL;
+
+    return ERR_PTR(ret);
 }
 /*
  * destroys the given cpupool
@@ -767,7 +768,7 @@ static void cpupool_cpu_remove_forced(unsigned int cpu)
  */
 int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 {
-    int ret;
+    int ret = 0;
     struct cpupool *c;
 
     switch ( op->op )
@@ -779,8 +780,10 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
         poolid = (op->cpupool_id == XEN_SYSCTL_CPUPOOL_PAR_ANY) ?
             CPUPOOLID_NONE: op->cpupool_id;
-        c = cpupool_create(poolid, op->sched_id, &ret);
-        if ( c != NULL )
+        c = cpupool_create(poolid, op->sched_id);
+        if ( IS_ERR(c) )
+            ret = PTR_ERR(c);
+        else
         {
             op->cpupool_id = c->cpupool_id;
             cpupool_put(c);
@@ -1003,12 +1006,11 @@ static struct notifier_block cpu_nfb = {
 static int __init cpupool_init(void)
 {
     unsigned int cpu;
-    int err;
 
     cpupool_gran_init();
 
-    cpupool0 = cpupool_create(0, 0, &err);
-    BUG_ON(cpupool0 == NULL);
+    cpupool0 = cpupool_create(0, 0);
+    BUG_ON(IS_ERR(cpupool0));
     cpupool_put(cpupool0);
     register_cpu_notifier(&cpu_nfb);
 
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index 6953cefa6e..92d0d49610 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -597,7 +597,7 @@ void sched_rm_cpu(unsigned int cpu);
 const cpumask_t *sched_get_opt_cpumask(enum sched_gran opt, unsigned int cpu);
 void schedule_dump(struct cpupool *c);
 struct scheduler *scheduler_get_default(void);
-struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr);
+struct scheduler *scheduler_alloc(unsigned int sched_id);
 void scheduler_free(struct scheduler *sched);
 int cpu_disable_scheduler(unsigned int cpu);
 int schedule_cpu_add(unsigned int cpu, struct cpupool *c);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 15:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 15:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46793.82938 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIqx-0006ZS-1u; Mon, 07 Dec 2020 15:55:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46793.82938; Mon, 07 Dec 2020 15:55:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIqw-0006ZK-VD; Mon, 07 Dec 2020 15:55:06 +0000
Received: by outflank-mailman (input) for mailman id 46793;
 Mon, 07 Dec 2020 15:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIqv-0006ZF-F4
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIqv-0003zO-CZ
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIqv-0001tx-B4
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=S5o0cLMiq0Xn2WA9gWpxuxuxHmPo2O3lcWV7YceqBfc=; b=y1uv6n1RtLwl20foyo3iaMIDB9
	WsJ/ntKTvZiuIgkN7j6DPCyBvwgIxnTbxePy61dW/+6q8G2tcrKeLuHbwAUuXkYab72zAMwAvPqPR
	uGPi2r81Z9x3cZ8yaRwKbGpmkc43oB9SY0xYY4w1KqnhegvRW+U8WWNOT3EcJ3E1UR20=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs: fix documentation about default scheduler
Message-Id: <E1kmIqv-0001tx-B4@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 15:55:05 +0000

commit 881966dc3b420369b4b39e6586531f58562d88d8
Author:     Roger Pau Monne <roger.pau@citrix.com>
AuthorDate: Tue Nov 17 10:32:58 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Mon Dec 7 15:44:52 2020 +0000

    docs: fix documentation about default scheduler
    
    Fix the command line document to account for the default scheduler in
    Kconfig being credit2 now, and the fact that it's selectable at build
    time and thus different builds could end up with different default
    schedulers.
    
    Fixes: dafd936dddbd ('Make credit2 the default scheduler')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/misc/xen-command-line.pandoc | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index f7db2b64aa..1cb1aee5ed 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1886,9 +1886,11 @@ with read and write permissions.
 ### sched
 > `= credit | credit2 | arinc653 | rtds | null`
 
-> Default: `sched=credit`
+> Default: `sched=credit2`
 
-Choose the default scheduler.
+Choose the default scheduler. Note the default scheduler is selectable via
+Kconfig and depends on enabled schedulers. Check
+`CONFIG_SCHED_DEFAULT` to see which scheduler is the default.
 
 ### sched_credit2_max_cpus_runqueue
 > `= <integer>`
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 07 15:55:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 07 Dec 2020 15:55:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.46794.82942 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIr7-0006aG-3L; Mon, 07 Dec 2020 15:55:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 46794.82942; Mon, 07 Dec 2020 15:55:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmIr7-0006a8-0R; Mon, 07 Dec 2020 15:55:17 +0000
Received: by outflank-mailman (input) for mailman id 46794;
 Mon, 07 Dec 2020 15:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIr5-0006a1-IO
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIr5-0003zR-H6
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmIr5-0001uc-FB
 for xen-changelog@lists.xenproject.org; Mon, 07 Dec 2020 15:55:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KMgw0+c1l4ENnLkQQWYCORYX2dLNSga5K/C0NpoKByI=; b=wFYXDWXqjHkF2dpUJ78FMMONny
	5660T5U5wefx1G+n7QFq+M2p3SpHXi/u1yGEwpTZ/JFBAexhSsDuAi+snd0XCmvgxFhR+FtspXnQ5
	Q5MNe0lcBOixd2lT7iupv7vUBYL+YsSk//Zb/OKalsuPu2+ROMpyDrJ/R2t+JMes1ZfY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs: remove stale README.incompatibilities
Message-Id: <E1kmIr5-0001uc-FB@xenbits.xenproject.org>
Date: Mon, 07 Dec 2020 15:55:15 +0000

commit 4b0e0db86194b5e9e18c9f2c10b3910f3394c56f
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Sep 9 12:52:13 2020 +0200
Commit:     Wei Liu <wl@xen.org>
CommitDate: Mon Dec 7 15:50:31 2020 +0000

    docs: remove stale README.incompatibilities
    
    It mentions just stale and obsolete distributions.
    They are not suitable to build current Xen, since a couple of years.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/examples/Makefile                 |  1 -
 tools/examples/README.incompatibilities | 38 ---------------------------------
 2 files changed, 39 deletions(-)

diff --git a/tools/examples/Makefile b/tools/examples/Makefile
index f86ed3a271..2a6c5444d4 100644
--- a/tools/examples/Makefile
+++ b/tools/examples/Makefile
@@ -3,7 +3,6 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 # Xen configuration dir and configs to go there.
 XEN_READMES = README
-XEN_READMES += README.incompatibilities
 
 XEN_CONFIGS += xlexample.hvm
 XEN_CONFIGS += xlexample.pvlinux
diff --git a/tools/examples/README.incompatibilities b/tools/examples/README.incompatibilities
deleted file mode 100644
index bb067bd419..0000000000
--- a/tools/examples/README.incompatibilities
+++ /dev/null
@@ -1,38 +0,0 @@
-Command Incompatibilities
-=========================
-
-Known incompatibilities with various commands on various distributions, and
-the workarounds we use.
-
-
-brctl
------
-
-brctl show <bridge> fails on SLES9 SP2.  Workaround is to use brctl show
-without arguments, and grep, though this would be difficult were you to need
-to check for a specific bridge-interface pair, since brctl does not show the 
-bridge name on every line.
-
-
-ifup / ifdown
--------------
-
-SuSE requires an extra parameter to ifup, which is created by calling getcfg
-appropriately.  See xen-network-common.sh for details.
-
-Gentoo doesn't have ifup/ifdown; appropriate alternatives are defined in
-xen-network-common.sh.
-
-
-ip
---
-
-Newer ip commands (from iproute2) do not accept the abbreviated syntax "ip r a
-..." etc.  "ip route add ..." must be used instead.
-
-
-sed
----
-
-\s is not supported in regexps on Debian etch (sed 4.1.2), Ubuntu 4.10.  We
-hand-craft character classes instead.
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 07:55:12 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 07:55:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47187.83577 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmXpy-0005OL-QB; Tue, 08 Dec 2020 07:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47187.83577; Tue, 08 Dec 2020 07:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmXpy-0005OD-N0; Tue, 08 Dec 2020 07:55:06 +0000
Received: by outflank-mailman (input) for mailman id 47187;
 Tue, 08 Dec 2020 07:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXpx-0005O8-FQ
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXpx-0008WK-Ea
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXpx-0004wq-C9
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Go+QuymRs1A/p5TYDBBREcyMBPhQ+4x2rZ+uu9fIh+k=; b=D4Cqae3sYCprAzS8GlsWKZcGrB
	Y27nDMu3DMMOP37bILuHoFJv8RycFJgp8ykoU+rKy8YSlmPeXxBZFBHhuIN1KCqhmKo/xHpTz5prn
	/0Mz2JWD7sRYkLPHU6RR93aoafIQxZv8bT+sg/dpba2niBbEJjxa00PqNORs/iFiiokE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/events: do some cleanups in evtchn_fifo_set_pending()
Message-Id: <E1kmXpx-0004wq-C9@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 07:55:05 +0000

commit 0919030638e733993edb8ace762227e440a0cb65
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 8 08:52:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 8 08:52:31 2020 +0100

    xen/events: do some cleanups in evtchn_fifo_set_pending()
    
    evtchn_fifo_set_pending() can be simplified a little bit. Especially
    testing for the fifo control block to exist can be moved out of the
    main if clause of the function enabling to avoid testing the LINKED bit
    twice.
    
    Suggested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/event_fifo.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index a6cca4798d..d508d57219 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -229,29 +229,24 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         goto done;
     }
 
+    /*
+     * Control block not mapped.  The guest must not unmask an
+     * event until the control block is initialized, so we can
+     * just drop the event.
+     */
+    if ( unlikely(!v->evtchn_fifo->control_block) )
+    {
+        printk(XENLOG_G_WARNING
+               "%pv has no FIFO event channel control block\n", v);
+        goto unlock;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
-         !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
+         !guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        event_word_t *tail_word;
-
-        /*
-         * Control block not mapped.  The guest must not unmask an
-         * event until the control block is initialized, so we can
-         * just drop the event.
-         */
-        if ( unlikely(!v->evtchn_fifo->control_block) )
-        {
-            printk(XENLOG_G_WARNING
-                   "%pv has no FIFO event channel control block\n", v);
-            goto unlock;
-        }
-
-        if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-            goto unlock;
-
         /*
          * If this event was a tail, the old queue is now empty and
          * its tail must be invalidated to prevent adding an event to
@@ -286,6 +281,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         linked = false;
         if ( q->tail )
         {
+            event_word_t *tail_word;
+
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
             linked = evtchn_fifo_set_link(d, tail_word, port);
         }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 07:55:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 07:55:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47188.83581 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmXq8-0005PP-T9; Tue, 08 Dec 2020 07:55:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47188.83581; Tue, 08 Dec 2020 07:55:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmXq8-0005PH-Pw; Tue, 08 Dec 2020 07:55:16 +0000
Received: by outflank-mailman (input) for mailman id 47188;
 Tue, 08 Dec 2020 07:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXq7-0005PA-Jf
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXq7-00005Q-Il
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmXq7-0004xW-H5
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 07:55:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zl4XyDioJatGJtqIursODpZlW2jy57/f/EVaFia5AqM=; b=YyO21Hw6/TGWgeaYclkM0zTI5k
	5X444mPBFvvh1O4oBzCLqJlNlViCv02mXkbQQsGHr7DATPZNtI6xAiwF5jllQLTneJNOpu7/f5ElK
	ZKFnh7DazGllK4lux5DBxOxCqQxu1WOaNXMjwHEr/1/N+b3MC737PJwfsHYHoXdSFWeY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxenstat: avoid build race
Message-Id: <E1kmXq7-0004xW-H5@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 07:55:15 +0000

commit 777e3590f154e6a8af560dd318b9465fa168db20
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 8 08:53:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 8 08:53:18 2020 +0100

    libxenstat: avoid build race
    
    Olaf reported observing
    
    xenstat_qmp.c:26:10: fatal error: _paths.h: No such file or directory
    .../tools/libs/stat/../../../tools/Rules.mk:153: xenstat_qmp.opic] Error 1
    
    Obviously _paths.h, when included by any of the sources, needs to be
    created in advance of compiling any of them, not just when compiling
    into non-PIC objects.
    
    Reported-by: Olaf Hering <olaf@aepfle.de>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/stat/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/libs/stat/Makefile b/tools/libs/stat/Makefile
index 8353e96946..c99508ae6b 100644
--- a/tools/libs/stat/Makefile
+++ b/tools/libs/stat/Makefile
@@ -30,7 +30,7 @@ APPEND_LDFLAGS += $(LDLIBS-y)
 
 include $(XEN_ROOT)/tools/libs/libs.mk
 
-$(LIB_OBJS): _paths.h
+$(LIB_OBJS) $(PIC_OBJS): _paths.h
 
 PYLIB=bindings/swig/python/_xenstat.so
 PYMOD=bindings/swig/python/xenstat.py
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47510.84064 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTE-0006Gd-1u; Tue, 08 Dec 2020 15:00:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47510.84064; Tue, 08 Dec 2020 15:00:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTD-0006GE-UP; Tue, 08 Dec 2020 15:00:03 +0000
Received: by outflank-mailman (input) for mailman id 47510;
 Tue, 08 Dec 2020 15:00:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTC-00068N-TC
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTC-00015y-QL
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTC-0002Pj-O9
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XR89icUkhhWUzxo0CBKb+urJSfA/qcsQKetF1Md+kuM=; b=QutjvLzX+hwftyvOreje80Asyv
	+yj9QSwhNHq89+jZgIWrYjhR32ap/+yhuQPOWGlA/Fdk2SiseTm4C8+ELJGkhuWUy10It8sstbkor
	MmeJpTbMZg0vK2/6bmJKBFbTR2zdFuN1Lk+8A1X6PsiwJLn77NqSE3eG/LudgxFsN1MU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/IRQ: make max number of guests for a shared IRQ configurable
Message-Id: <E1kmeTC-0002Pj-O9@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:02 +0000

commit e373bc1bdc593564e15d11a7a50f74968907ee5f
Author:     Igor Druzhinin <igor.druzhinin@citrix.com>
AuthorDate: Mon Dec 7 14:49:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:49:30 2020 +0100

    x86/IRQ: make max number of guests for a shared IRQ configurable
    
    ... and increase the default to 16.
    
    Current limit of 7 is too restrictive for modern systems where one GSI
    could be shared by potentially many PCI INTx sources where each of them
    corresponds to a device passed through to its own guest. Some systems do not
    apply due dilligence in swizzling INTx links in case e.g. INTA is declared as
    interrupt pin for the majority of PCI devices behind a single router,
    resulting in overuse of a GSI.
    
    Introduce a new command line option to configure that limit and dynamically
    allocate an array of the necessary size. Set the default size now to 16 which
    is higher than 7 but could later be increased even more if necessary.
    
    Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/xen-command-line.pandoc | 10 ++++++++++
 xen/arch/x86/irq.c                | 26 +++++++++++++++++++-------
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index b4a0d60c11..53e676b30f 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1641,6 +1641,16 @@ This option is ignored in **pv-shim** mode.
 ### nr_irqs (x86)
 > `= <integer>`
 
+### irq-max-guests (x86)
+> `= <integer>`
+
+> Default: `16`
+
+Maximum number of guests any individual IRQ could be shared between,
+i.e. a limit on the number of guests it is possible to start each having
+assigned a device sharing a common interrupt line.  Accepts values between
+1 and 255.
+
 ### numa (x86)
 > `= on | off | fake=<integer> | noacpi`
 
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 3387c1b5c3..1a60160916 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -42,6 +42,10 @@ integer_param("nr_irqs", nr_irqs);
 int __read_mostly opt_irq_vector_map = OPT_IRQ_VECTOR_MAP_DEFAULT;
 custom_param("irq_vector_map", parse_irq_vector_map_param);
 
+/* Max number of guests IRQ could be shared with */
+static unsigned char __read_mostly irq_max_guests;
+integer_param("irq-max-guests", irq_max_guests);
+
 vmask_t global_used_vector_map;
 
 struct irq_desc __read_mostly *irq_desc = NULL;
@@ -435,6 +439,9 @@ int __init init_irq_data(void)
     for ( ; irq < nr_irqs; irq++ )
         irq_to_desc(irq)->irq = irq;
 
+    if ( !irq_max_guests )
+        irq_max_guests = 16;
+
 #ifdef CONFIG_PV
     /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
     set_bit(LEGACY_SYSCALL_VECTOR, used_vectors);
@@ -1028,7 +1035,6 @@ int __init setup_irq(unsigned int irq, unsigned int irqflags,
  * HANDLING OF GUEST-BOUND PHYSICAL IRQS
  */
 
-#define IRQ_MAX_GUESTS 7
 typedef struct {
     u8 nr_guests;
     u8 in_flight;
@@ -1039,7 +1045,7 @@ typedef struct {
 #define ACKTYPE_EOI    2     /* EOI on the CPU that was interrupted  */
     cpumask_var_t cpu_eoi_map; /* CPUs that need to EOI this interrupt */
     struct timer eoi_timer;
-    struct domain *guest[IRQ_MAX_GUESTS];
+    struct domain *guest[];
 } irq_guest_action_t;
 
 static irq_guest_action_t *guest_action(const struct irq_desc *desc)
@@ -1553,7 +1559,8 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         if ( newaction == NULL )
         {
             spin_unlock_irq(&desc->lock);
-            if ( (newaction = xmalloc(irq_guest_action_t)) != NULL &&
+            if ( (newaction = xmalloc_flex_struct(irq_guest_action_t, guest,
+                                                  irq_max_guests)) != NULL &&
                  zalloc_cpumask_var(&newaction->cpu_eoi_map) )
                 goto retry;
             xfree(newaction);
@@ -1622,11 +1629,12 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto retry;
     }
 
-    if ( action->nr_guests == IRQ_MAX_GUESTS )
+    if ( action->nr_guests == irq_max_guests )
     {
-        printk(XENLOG_G_INFO "Cannot bind IRQ%d to dom%d. "
-               "Already at max share.\n",
-               pirq->pirq, v->domain->domain_id);
+        printk(XENLOG_G_INFO
+               "Cannot bind IRQ%d to %pd: already at max share %u"
+               " (increase with irq-max-guests= option)\n",
+               pirq->pirq, v->domain, irq_max_guests);
         rc = -EBUSY;
         goto unlock_out;
     }
@@ -2510,6 +2518,10 @@ static void dump_irqs(unsigned char key)
 
 static int __init setup_dump_irqs(void)
 {
+    /* In lieu of being able to live in init_irq_data(). */
+    BUILD_BUG_ON(sizeof(irq_max_guests) >
+                 sizeof_field(irq_guest_action_t, nr_guests));
+
     register_keyhandler('i', dump_irqs, "dump interrupt bindings", 1);
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47512.84068 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTO-0006dx-3S; Tue, 08 Dec 2020 15:00:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47512.84068; Tue, 08 Dec 2020 15:00:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTN-0006dp-W9; Tue, 08 Dec 2020 15:00:13 +0000
Received: by outflank-mailman (input) for mailman id 47512;
 Tue, 08 Dec 2020 15:00:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTN-0006dj-0H
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTM-000161-Vg
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTM-0002RN-TL
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DPK9Lh90++B04bnFHeH7xqorogShJMyR2nv6pWJLS64=; b=S9vmDJpCuIUODZidvwjH2s0IHV
	TjzC1np2rfOM6bd8rLBG7ZZPaOa7bE55/+eicP8AUJZpIof9gAE8ha5M4t7+XL7Abb+p6620qgTTf
	MIFVdRKA5LFexlm41QSX6v2NJqcpge/1zh0SwmNl1iXsWP+3+AN4sWNbQ6S/c+dS3F6s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/IRQ: allocate guest array of max size only for shareable IRQs
Message-Id: <E1kmeTM-0002RN-TL@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:12 +0000

commit b7c333016e3d6adf38e80b4e6b121950da092405
Author:     Igor Druzhinin <igor.druzhinin@citrix.com>
AuthorDate: Mon Dec 7 14:52:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:52:35 2020 +0100

    x86/IRQ: allocate guest array of max size only for shareable IRQs
    
    ... and increase default "irq-max-guests" to 32.
    
    It's not necessary to have an array of a size more than 1 for non-shareable
    IRQs and it might impact scalability in case of high "irq-max-guests"
    values being used - every IRQ in the system including MSIs would be
    supplied with an array of that size.
    
    Since it's now less impactful to use higher "irq-max-guests" value - bump
    the default to 32. That should give more headroom for future systems.
    
    Requested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/xen-command-line.pandoc | 2 +-
 xen/arch/x86/irq.c                | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index 53e676b30f..f7db2b64aa 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1644,7 +1644,7 @@ This option is ignored in **pv-shim** mode.
 ### irq-max-guests (x86)
 > `= <integer>`
 
-> Default: `16`
+> Default: `32`
 
 Maximum number of guests any individual IRQ could be shared between,
 i.e. a limit on the number of guests it is possible to start each having
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 1a60160916..f82c93dfdc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -440,7 +440,7 @@ int __init init_irq_data(void)
         irq_to_desc(irq)->irq = irq;
 
     if ( !irq_max_guests )
-        irq_max_guests = 16;
+        irq_max_guests = 32;
 
 #ifdef CONFIG_PV
     /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
@@ -1532,6 +1532,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
 {
     struct irq_desc         *desc;
     irq_guest_action_t *action, *newaction = NULL;
+    unsigned int        max_nr_guests = will_share ? irq_max_guests : 1;
     int                 rc = 0;
 
     WARN_ON(!spin_is_locked(&v->domain->event_lock));
@@ -1560,7 +1561,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         {
             spin_unlock_irq(&desc->lock);
             if ( (newaction = xmalloc_flex_struct(irq_guest_action_t, guest,
-                                                  irq_max_guests)) != NULL &&
+                                                  max_nr_guests)) != NULL &&
                  zalloc_cpumask_var(&newaction->cpu_eoi_map) )
                 goto retry;
             xfree(newaction);
@@ -1629,7 +1630,7 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
         goto retry;
     }
 
-    if ( action->nr_guests == irq_max_guests )
+    if ( action->nr_guests >= max_nr_guests )
     {
         printk(XENLOG_G_INFO
                "Cannot bind IRQ%d to %pd: already at max share %u"
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47513.84072 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTY-0006fH-4v; Tue, 08 Dec 2020 15:00:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47513.84072; Tue, 08 Dec 2020 15:00:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTY-0006f9-1d; Tue, 08 Dec 2020 15:00:24 +0000
Received: by outflank-mailman (input) for mailman id 47513;
 Tue, 08 Dec 2020 15:00:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTX-0006ez-3l
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTX-00016Y-2z
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTX-0002SE-23
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=o2qgFBPdnr85fpklWTk/fJHVGLcuI9rSpGqGSTYdyXs=; b=na6PdtLGGlyareZtmF6BTVvuxa
	z3UY5zVKVCTdL2FkP4V7Ok+6F4KKMEJ/gPTGsa6a8AwN95rUmRRJRJ1MT6y/gEahJFZLR15Wd1s9b
	DBAATKIX63W9vTXckGzC/uzri7FIrzAYoRYj59rU1iiAIUfGy803OjWAMQ+5XG+YhnbA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/vIO-APIC: make use of xmalloc_flex_struct()
Message-Id: <E1kmeTX-0002SE-23@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:23 +0000

commit d218fb11884346bb079fa2226ab8786a7bfeee16
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Mon Dec 7 14:53:20 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:53:20 2020 +0100

    x86/vIO-APIC: make use of xmalloc_flex_struct()
    
    ... instead of effectively open-coding it in a type-unsafe way. Drop
    hvm_vioapic_size() altogether, folding the other use in a memset()
    invocation into the subsequent loop.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/vioapic.c        | 7 ++++---
 xen/include/asm-x86/hvm/vioapic.h | 1 -
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index e64abee7a9..7c462a44d4 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -622,9 +622,9 @@ void vioapic_reset(struct domain *d)
         unsigned int nr_pins = vioapic->nr_pins, base_gsi = vioapic->base_gsi;
         unsigned int pin;
 
-        memset(vioapic, 0, hvm_vioapic_size(nr_pins));
+        memset(vioapic, 0, offsetof(typeof(*vioapic), redirtbl));
         for ( pin = 0; pin < nr_pins; pin++ )
-            vioapic->redirtbl[pin].fields.mask = 1;
+            vioapic->redirtbl[pin] = (union vioapic_redir_entry){ .fields.mask = 1 };
 
         if ( !is_hardware_domain(d) )
         {
@@ -685,7 +685,8 @@ int vioapic_init(struct domain *d)
         }
 
         if ( (domain_vioapic(d, i) =
-              xmalloc_bytes(hvm_vioapic_size(nr_pins))) == NULL )
+              xmalloc_flex_struct(struct hvm_vioapic, redirtbl,
+                                  nr_pins)) == NULL )
         {
             vioapic_free(d, nr_vioapics);
             return -ENOMEM;
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index d6f4e12d54..36b64d20d6 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -56,7 +56,6 @@ struct hvm_vioapic {
     };
 };
 
-#define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
 #define domain_vioapic(d, i) ((d)->arch.hvm.vioapic[i])
 #define vioapic_domain(v) ((v)->domain)
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47514.84076 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTi-0006gb-6L; Tue, 08 Dec 2020 15:00:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47514.84076; Tue, 08 Dec 2020 15:00:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTi-0006gT-3D; Tue, 08 Dec 2020 15:00:34 +0000
Received: by outflank-mailman (input) for mailman id 47514;
 Tue, 08 Dec 2020 15:00:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTh-0006gI-8T
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTh-00016k-7j
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTh-0002TJ-5q
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=SyQTiXzwCike2PWxgnNE0wQYGpXg8lxUqSbAwCq4uo4=; b=ejpJgfo+JryL3x1kzioAZ65bnR
	XYh2xLSt/clvoZ894jJsMjn0HY2rfZRO+GgYuTN6fbdZC3iH9w30RrY4axZvORgIkNXlXpfF9oPBz
	k9mljXckQgMKR61ZiwfnHmPyw9POhQD8HdVU3jOP4PCuCF06EI7yT+qnSToocnqlCEow=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/vPMU: make use of xmalloc_flex_struct()
Message-Id: <E1kmeTh-0002TJ-5q@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:33 +0000

commit 826a6dd030fe7d2a62b019e7d6e51ab79227f4aa
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Mon Dec 7 14:54:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:54:08 2020 +0100

    x86/vPMU: make use of xmalloc_flex_struct()
    
    ... instead of effectively open-coding it in a type-unsafe way. Drop the
    regs_sz variable altogether, replacing other uses suitably.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/cpu/vpmu_amd.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu_amd.c b/xen/arch/x86/cpu/vpmu_amd.c
index eba47cd2a0..38972089ab 100644
--- a/xen/arch/x86/cpu/vpmu_amd.c
+++ b/xen/arch/x86/cpu/vpmu_amd.c
@@ -44,9 +44,6 @@ static const u32 __read_mostly *counters;
 static const u32 __read_mostly *ctrls;
 static bool_t __read_mostly k7_counters_mirrored;
 
-/* Total size of PMU registers block (copied to/from PV(H) guest) */
-static unsigned int __read_mostly regs_sz;
-
 #define F10H_NUM_COUNTERS   4
 #define F15H_NUM_COUNTERS   6
 #define MAX_NUM_COUNTERS    F15H_NUM_COUNTERS
@@ -156,12 +153,9 @@ static inline u32 get_fam15h_addr(u32 addr)
 
 static void amd_vpmu_init_regs(struct xen_pmu_amd_ctxt *ctxt)
 {
-    unsigned i;
-    uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls);
-
-    memset(&ctxt->regs[0], 0, regs_sz);
-    for ( i = 0; i < num_counters; i++ )
-        ctrl_regs[i] = ctrl_rsvd[i];
+    memset(&ctxt->regs[0], 0, num_counters * sizeof(ctxt->regs[0]));
+    memcpy(&ctxt->regs[num_counters], &ctrl_rsvd[0],
+           num_counters * sizeof(ctxt->regs[0]));
 }
 
 static void amd_vpmu_set_msr_bitmap(struct vcpu *v)
@@ -242,7 +236,8 @@ static int amd_vpmu_load(struct vcpu *v, bool_t from_guest)
         ctxt = vpmu->context;
         ctrl_regs = vpmu_reg_pointer(ctxt, ctrls);
 
-        memcpy(&ctxt->regs[0], &guest_ctxt->regs[0], regs_sz);
+        memcpy(&ctxt->regs[0], &guest_ctxt->regs[0],
+               2 * num_counters * sizeof(ctxt->regs[0]));
 
         for ( i = 0; i < num_counters; i++ )
         {
@@ -316,7 +311,8 @@ static int amd_vpmu_save(struct vcpu *v,  bool_t to_guest)
         ASSERT(!has_vlapic(v->domain));
         ctxt = vpmu->context;
         guest_ctxt = &vpmu->xenpmu_data->pmu.c.amd;
-        memcpy(&guest_ctxt->regs[0], &ctxt->regs[0], regs_sz);
+        memcpy(&guest_ctxt->regs[0], &ctxt->regs[0],
+               2 * num_counters * sizeof(ctxt->regs[0]));
     }
 
     return 1;
@@ -508,7 +504,8 @@ int svm_vpmu_initialise(struct vcpu *v)
     if ( !counters )
         return -EINVAL;
 
-    ctxt = xmalloc_bytes(sizeof(*ctxt) + regs_sz);
+    ctxt = xmalloc_flex_struct(struct xen_pmu_amd_ctxt, regs,
+                               2 * num_counters);
     if ( !ctxt )
     {
         printk(XENLOG_G_WARNING "Insufficient memory for PMU, "
@@ -565,8 +562,6 @@ static int __init common_init(void)
         ctrl_rsvd[i] &= CTRL_RSVD_MASK;
     }
 
-    regs_sz = 2 * sizeof(uint64_t) * num_counters;
-
     return 0;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47515.84081 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTs-0006hh-97; Tue, 08 Dec 2020 15:00:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47515.84081; Tue, 08 Dec 2020 15:00:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeTs-0006hX-4u; Tue, 08 Dec 2020 15:00:44 +0000
Received: by outflank-mailman (input) for mailman id 47515;
 Tue, 08 Dec 2020 15:00:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTr-0006hO-CU
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTr-00016y-Bb
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeTr-0002UJ-Aj
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=83zIJBbNM+Z+FUyeo/1lhbN4ugPf1VS9Ct1NfBrxGZM=; b=DxB+7UulY+cZCR4CKAiJZmOWfw
	lZJ0nZBFG5dhSNOHtjiFZ7ZvO0BvOZY54h5iXEN2HBPjDlWN/Y3SCPchkv3VBt6vH8Cb2VxsKnv4G
	wqTM32atRfxGSYHsX7r4MYaDfRBnVxG18co3lzPiH+nYd9D+r0x84ZzPVc8npM82GXnE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/vmap: handle superpages in vmap_to_mfn()
Message-Id: <E1kmeTr-0002UJ-Aj@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:43 +0000

commit 3ec53aa79905edc3891b8267123d88a221553370
Author:     Hongyan Xia <hongyxia@amazon.com>
AuthorDate: Mon Dec 7 14:54:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 14:54:44 2020 +0100

    x86/vmap: handle superpages in vmap_to_mfn()
    
    There is simply no guarantee that vmap won't return superpages to the
    caller. It can happen if the list of MFNs are contiguous, or we simply
    have a large granularity. Although rare, if such things do happen, we
    will simply hit BUG_ON() and crash.
    
    Introduce xen_map_to_mfn() to translate any mapped Xen address to mfn
    regardless of page size, and wrap vmap_to_mfn() around it.
    
    Signed-off-by: Hongyan Xia <hongyxia@amazon.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/mm.c          | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/page.h |  2 +-
 xen/include/xen/mm.h       |  3 +++
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 5a50339284..723cc1070f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5194,6 +5194,62 @@ l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
         }                                          \
     } while ( false )
 
+/* Translate mapped Xen address to MFN. */
+mfn_t xen_map_to_mfn(unsigned long va)
+{
+#define CHECK_MAPPED(cond)          \
+    do {                            \
+        if ( !(cond) )              \
+        {                           \
+            ASSERT_UNREACHABLE();   \
+            ret = INVALID_MFN;      \
+            goto out;               \
+        }                           \
+    } while ( false )
+
+    bool locking = system_state > SYS_STATE_boot;
+    unsigned int l2_offset = l2_table_offset(va);
+    unsigned int l1_offset = l1_table_offset(va);
+    const l3_pgentry_t *pl3e = virt_to_xen_l3e(va);
+    const l2_pgentry_t *pl2e = NULL;
+    const l1_pgentry_t *pl1e = NULL;
+    struct page_info *l3page;
+    mfn_t ret;
+
+    L3T_INIT(l3page);
+    CHECK_MAPPED(pl3e);
+    l3page = virt_to_page(pl3e);
+    L3T_LOCK(l3page);
+
+    CHECK_MAPPED(l3e_get_flags(*pl3e) & _PAGE_PRESENT);
+    if ( l3e_get_flags(*pl3e) & _PAGE_PSE )
+    {
+        ret = mfn_add(l3e_get_mfn(*pl3e),
+                      (l2_offset << PAGETABLE_ORDER) + l1_offset);
+        goto out;
+    }
+
+    pl2e = map_l2t_from_l3e(*pl3e) + l2_offset;
+    CHECK_MAPPED(l2e_get_flags(*pl2e) & _PAGE_PRESENT);
+    if ( l2e_get_flags(*pl2e) & _PAGE_PSE )
+    {
+        ret = mfn_add(l2e_get_mfn(*pl2e), l1_offset);
+        goto out;
+    }
+
+    pl1e = map_l1t_from_l2e(*pl2e) + l1_offset;
+    CHECK_MAPPED(l1e_get_flags(*pl1e) & _PAGE_PRESENT);
+    ret = l1e_get_mfn(*pl1e);
+
+#undef CHECK_MAPPED
+ out:
+    L3T_UNLOCK(l3page);
+    unmap_domain_page(pl1e);
+    unmap_domain_page(pl2e);
+    unmap_domain_page(pl3e);
+    return ret;
+}
+
 int map_pages_to_xen(
     unsigned long virt,
     mfn_t mfn,
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 7a771baf7c..082c14a662 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -291,7 +291,7 @@ void copy_page_sse2(void *, const void *);
 #define pfn_to_paddr(pfn)   __pfn_to_paddr(pfn)
 #define paddr_to_pfn(pa)    __paddr_to_pfn(pa)
 #define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
-#define vmap_to_mfn(va)     l1e_get_mfn(*virt_to_xen_l1e((unsigned long)(va)))
+#define vmap_to_mfn(va)     xen_map_to_mfn((unsigned long)(va))
 #define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
 
 #endif /* !defined(__ASSEMBLY__) */
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index f7975b2df0..85a8df9948 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -184,6 +184,9 @@ int map_pages_to_xen(
 /* Alter the permissions of a range of Xen virtual address space. */
 int modify_xen_mappings(unsigned long s, unsigned long e, unsigned int flags);
 int destroy_xen_mappings(unsigned long v, unsigned long e);
+/* Retrieve the MFN mapped by VA in Xen virtual address space. */
+mfn_t xen_map_to_mfn(unsigned long va);
+
 /*
  * Create only non-leaf page table entries for the
  * page range in Xen virtual address space.
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:00:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:00:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47516.84085 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeU3-0006nC-CO; Tue, 08 Dec 2020 15:00:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47516.84085; Tue, 08 Dec 2020 15:00:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeU3-0006n0-6y; Tue, 08 Dec 2020 15:00:55 +0000
Received: by outflank-mailman (input) for mailman id 47516;
 Tue, 08 Dec 2020 15:00:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeU1-0006mq-Ik
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeU1-00017A-H3
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeU1-0002VX-Eb
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:00:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PNaYt4XQ+NhMLEYz2P39ndFTgIg3ca6FkFCSa7BGpBM=; b=hUUT4ayxOGN8w9w1ZWzO51EkH2
	+6k8Or9n+0CKeXpniBLkqISZtizzeuECM6ax5OJ3U7F/BQoWrNeVyFqfzENsn8kcY0e0cHe3lshF/
	L/NGp/+m/XywM5QuwykgESSLFoiAdnf6k7rwW6DKNpfAA6S3bdrWa2biRfV/Qmif/smA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: switch cpupool id to unsigned
Message-Id: <E1kmeU1-0002VX-Eb@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:00:53 +0000

commit 30d430b2126697dda0bd53d19fe267fb4d30e9b8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:17:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:17:50 2020 +0100

    xen/cpupool: switch cpupool id to unsigned
    
    The cpupool id is an unsigned value in the public interface header, so
    there is no reason why it is a signed value in struct cpupool.
    
    Switch it to unsigned int.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c    |  2 +-
 xen/common/sched/cpupool.c | 48 +++++++++++++++++++++++-----------------------
 xen/common/sched/private.h |  8 ++++----
 xen/include/xen/sched.h    |  4 ++--
 4 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index f8c81592af..6063f6d9ea 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -757,7 +757,7 @@ void sched_destroy_vcpu(struct vcpu *v)
     }
 }
 
-int sched_init_domain(struct domain *d, int poolid)
+int sched_init_domain(struct domain *d, unsigned int poolid)
 {
     void *sdom;
     int ret;
diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 84f326ea63..01fa71dd00 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -187,7 +187,7 @@ static struct cpupool *alloc_cpupool_struct(void)
  * the searched id is returned
  * returns NULL if not found.
  */
-static struct cpupool *__cpupool_find_by_id(int id, bool exact)
+static struct cpupool *__cpupool_find_by_id(unsigned int id, bool exact)
 {
     struct cpupool **q;
 
@@ -200,12 +200,12 @@ static struct cpupool *__cpupool_find_by_id(int id, bool exact)
     return (!exact || (*q == NULL) || ((*q)->cpupool_id == id)) ? *q : NULL;
 }
 
-static struct cpupool *cpupool_find_by_id(int poolid)
+static struct cpupool *cpupool_find_by_id(unsigned int poolid)
 {
     return __cpupool_find_by_id(poolid, true);
 }
 
-static struct cpupool *__cpupool_get_by_id(int poolid, bool exact)
+static struct cpupool *__cpupool_get_by_id(unsigned int poolid, bool exact)
 {
     struct cpupool *c;
     spin_lock(&cpupool_lock);
@@ -216,12 +216,12 @@ static struct cpupool *__cpupool_get_by_id(int poolid, bool exact)
     return c;
 }
 
-struct cpupool *cpupool_get_by_id(int poolid)
+struct cpupool *cpupool_get_by_id(unsigned int poolid)
 {
     return __cpupool_get_by_id(poolid, true);
 }
 
-static struct cpupool *cpupool_get_next_by_id(int poolid)
+static struct cpupool *cpupool_get_next_by_id(unsigned int poolid)
 {
     return __cpupool_get_by_id(poolid, false);
 }
@@ -243,11 +243,11 @@ void cpupool_put(struct cpupool *pool)
  * - unknown scheduler
  */
 static struct cpupool *cpupool_create(
-    int poolid, unsigned int sched_id, int *perr)
+    unsigned int poolid, unsigned int sched_id, int *perr)
 {
     struct cpupool *c;
     struct cpupool **q;
-    int last = 0;
+    unsigned int last = 0;
 
     *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
@@ -256,7 +256,7 @@ static struct cpupool *cpupool_create(
     /* One reference for caller, one reference for cpupool_destroy(). */
     atomic_set(&c->refcnt, 2);
 
-    debugtrace_printk("cpupool_create(pool=%d,sched=%u)\n", poolid, sched_id);
+    debugtrace_printk("cpupool_create(pool=%u,sched=%u)\n", poolid, sched_id);
 
     spin_lock(&cpupool_lock);
 
@@ -295,7 +295,7 @@ static struct cpupool *cpupool_create(
 
     spin_unlock(&cpupool_lock);
 
-    debugtrace_printk("Created cpupool %d with scheduler %s (%s)\n",
+    debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
                       c->cpupool_id, c->sched->name, c->sched->opt_name);
 
     *perr = 0;
@@ -337,7 +337,7 @@ static int cpupool_destroy(struct cpupool *c)
 
     cpupool_put(c);
 
-    debugtrace_printk("cpupool_destroy(pool=%d)\n", c->cpupool_id);
+    debugtrace_printk("cpupool_destroy(pool=%u)\n", c->cpupool_id);
     return 0;
 }
 
@@ -521,7 +521,7 @@ static long cpupool_unassign_cpu_helper(void *info)
     struct cpupool *c = info;
     long ret;
 
-    debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d)\n",
+    debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d)\n",
                       cpupool_cpu_moving->cpupool_id, cpupool_moving_cpu);
     spin_lock(&cpupool_lock);
 
@@ -551,7 +551,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
     int ret;
     unsigned int master_cpu;
 
-    debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d)\n",
+    debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d)\n",
                       c->cpupool_id, cpu);
 
     if ( !cpu_online(cpu) )
@@ -561,7 +561,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
     ret = cpupool_unassign_cpu_start(c, master_cpu);
     if ( ret )
     {
-        debugtrace_printk("cpupool_unassign_cpu(pool=%d,cpu=%d) ret %d\n",
+        debugtrace_printk("cpupool_unassign_cpu(pool=%u,cpu=%d) ret %d\n",
                           c->cpupool_id, cpu, ret);
         return ret;
     }
@@ -582,7 +582,7 @@ static int cpupool_unassign_cpu(struct cpupool *c, unsigned int cpu)
  * - pool does not exist
  * - no cpu assigned to pool
  */
-int cpupool_add_domain(struct domain *d, int poolid)
+int cpupool_add_domain(struct domain *d, unsigned int poolid)
 {
     struct cpupool *c;
     int rc;
@@ -604,7 +604,7 @@ int cpupool_add_domain(struct domain *d, int poolid)
         rc = 0;
     }
     spin_unlock(&cpupool_lock);
-    debugtrace_printk("cpupool_add_domain(dom=%d,pool=%d) n_dom %d rc %d\n",
+    debugtrace_printk("cpupool_add_domain(dom=%d,pool=%u) n_dom %d rc %d\n",
                       d->domain_id, poolid, n_dom, rc);
     return rc;
 }
@@ -614,7 +614,7 @@ int cpupool_add_domain(struct domain *d, int poolid)
  */
 void cpupool_rm_domain(struct domain *d)
 {
-    int cpupool_id;
+    unsigned int cpupool_id;
     int n_dom;
 
     if ( d->cpupool == NULL )
@@ -625,7 +625,7 @@ void cpupool_rm_domain(struct domain *d)
     n_dom = d->cpupool->n_dom;
     d->cpupool = NULL;
     spin_unlock(&cpupool_lock);
-    debugtrace_printk("cpupool_rm_domain(dom=%d,pool=%d) n_dom %d\n",
+    debugtrace_printk("cpupool_rm_domain(dom=%d,pool=%u) n_dom %d\n",
                       d->domain_id, cpupool_id, n_dom);
     return;
 }
@@ -767,7 +767,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
     case XEN_SYSCTL_CPUPOOL_OP_CREATE:
     {
-        int poolid;
+        unsigned int poolid;
 
         poolid = (op->cpupool_id == XEN_SYSCTL_CPUPOOL_PAR_ANY) ?
             CPUPOOLID_NONE: op->cpupool_id;
@@ -811,7 +811,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
         const cpumask_t *cpus;
 
         cpu = op->cpu;
-        debugtrace_printk("cpupool_assign_cpu(pool=%d,cpu=%d)\n",
+        debugtrace_printk("cpupool_assign_cpu(pool=%u,cpu=%u)\n",
                           op->cpupool_id, cpu);
 
         spin_lock(&cpupool_lock);
@@ -844,7 +844,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
     addcpu_out:
         spin_unlock(&cpupool_lock);
-        debugtrace_printk("cpupool_assign_cpu(pool=%d,cpu=%d) ret %d\n",
+        debugtrace_printk("cpupool_assign_cpu(pool=%u,cpu=%u) ret %d\n",
                           op->cpupool_id, cpu, ret);
 
     }
@@ -885,7 +885,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
             rcu_unlock_domain(d);
             break;
         }
-        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%d\n",
+        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%u\n",
                           d->domain_id, op->cpupool_id);
         ret = -ENOENT;
         spin_lock(&cpupool_lock);
@@ -895,7 +895,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
             ret = cpupool_move_domain_locked(d, c);
 
         spin_unlock(&cpupool_lock);
-        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%d ret %d\n",
+        debugtrace_printk("cpupool move_domain(dom=%d)->pool=%u ret %d\n",
                           d->domain_id, op->cpupool_id, ret);
         rcu_unlock_domain(d);
     }
@@ -916,7 +916,7 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
     return ret;
 }
 
-int cpupool_get_id(const struct domain *d)
+unsigned int cpupool_get_id(const struct domain *d)
 {
     return d->cpupool ? d->cpupool->cpupool_id : CPUPOOLID_NONE;
 }
@@ -946,7 +946,7 @@ void dump_runq(unsigned char key)
 
     for_each_cpupool(c)
     {
-        printk("Cpupool %d:\n", (*c)->cpupool_id);
+        printk("Cpupool %u:\n", (*c)->cpupool_id);
         printk("Cpus: %*pbl\n", CPUMASK_PR((*c)->cpu_valid));
         sched_gran_print((*c)->gran, cpupool_get_granularity(*c));
         schedule_dump(*c);
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index 685992cab9..e69d9be1e8 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -505,8 +505,8 @@ static inline void sched_unit_unpause(const struct sched_unit *unit)
 
 struct cpupool
 {
-    int              cpupool_id;
-#define CPUPOOLID_NONE    (-1)
+    unsigned int     cpupool_id;
+#define CPUPOOLID_NONE    (~0U)
     unsigned int     n_dom;
     cpumask_var_t    cpu_valid;      /* all cpus assigned to pool */
     cpumask_var_t    res_valid;      /* all scheduling resources of pool */
@@ -601,9 +601,9 @@ int cpu_disable_scheduler(unsigned int cpu);
 int schedule_cpu_add(unsigned int cpu, struct cpupool *c);
 int schedule_cpu_rm(unsigned int cpu);
 int sched_move_domain(struct domain *d, struct cpupool *c);
-struct cpupool *cpupool_get_by_id(int poolid);
+struct cpupool *cpupool_get_by_id(unsigned int poolid);
 void cpupool_put(struct cpupool *pool);
-int cpupool_add_domain(struct domain *d, int poolid);
+int cpupool_add_domain(struct domain *d, unsigned int poolid);
 void cpupool_rm_domain(struct domain *d);
 
 #endif /* __XEN_SCHED_IF_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 4c380fd4b2..31abbe7a99 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -693,7 +693,7 @@ void noreturn asm_domain_crash_synchronous(unsigned long addr);
 void scheduler_init(void);
 int  sched_init_vcpu(struct vcpu *v);
 void sched_destroy_vcpu(struct vcpu *v);
-int  sched_init_domain(struct domain *d, int poolid);
+int  sched_init_domain(struct domain *d, unsigned int poolid);
 void sched_destroy_domain(struct domain *d);
 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
 long sched_adjust_global(struct xen_sysctl_scheduler_op *);
@@ -1091,7 +1091,7 @@ static always_inline bool is_cpufreq_controller(const struct domain *d)
 
 int cpupool_move_domain(struct domain *d, struct cpupool *c);
 int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op);
-int cpupool_get_id(const struct domain *d);
+unsigned int cpupool_get_id(const struct domain *d);
 const cpumask_t *cpupool_valid_cpus(const struct cpupool *pool);
 extern void dump_runq(unsigned char key);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:01:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:01:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47517.84088 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUD-0006of-DG; Tue, 08 Dec 2020 15:01:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47517.84088; Tue, 08 Dec 2020 15:01:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUD-0006oY-AM; Tue, 08 Dec 2020 15:01:05 +0000
Received: by outflank-mailman (input) for mailman id 47517;
 Tue, 08 Dec 2020 15:01:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUB-0006oI-Lr
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUB-00017V-L4
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUB-0002Wg-K1
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yxf5KYfJBTHOzTPdLV3ErTPXqQBMegPB+ntWEZHv8sA=; b=Nt28pCwQ5K6L8vcbL5H9a21JLP
	XMLq4DiwPS0HqmzcEBf0XJ+AFgGIUEVAdPTBn0sVP0nTeZeTn+f4podaNNbfY/BpYP+q7Ft8xGiaA
	O0y/lQD0Ua9u9upow/8xwwU1RQetlyN1mL2Q/b2N13sfJGpfAsWH9M5NxJ1NUekDGuS4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: switch cpupool list to normal list interface
Message-Id: <E1kmeUB-0002Wg-K1@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:01:03 +0000

commit d5ce1f6791342cf88aa2f5be500146820e6506ac
Author:     From: Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:18:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:18:47 2020 +0100

    xen/cpupool: switch cpupool list to normal list interface
    
    Instead of open coding something like a linked list just use the
    available functionality from list.h.
    
    The allocation of a new cpupool id is not aware of a possible wrap.
    Fix that. We don't, however, consider the case of extremely many pools
    (beyond 4 billion) as something which needs explicitly handling right
    now. First and foremost there would need to be systems with 4 billion
    CPUs to make this many pools a sensible thing to have.
    
    While adding the required new include to private.h sort the includes.
    
    Signed-off-by: From: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/cpupool.c | 100 ++++++++++++++++++++++++---------------------
 xen/common/sched/private.h |   4 +-
 2 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 01fa71dd00..714cd47ae9 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -16,6 +16,7 @@
 #include <xen/init.h>
 #include <xen/keyhandler.h>
 #include <xen/lib.h>
+#include <xen/list.h>
 #include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
@@ -23,13 +24,10 @@
 
 #include "private.h"
 
-#define for_each_cpupool(ptr)    \
-    for ((ptr) = &cpupool_list; *(ptr) != NULL; (ptr) = &((*(ptr))->next))
-
 struct cpupool *cpupool0;                /* Initial cpupool with Dom0 */
 cpumask_t cpupool_free_cpus;             /* cpus not in any cpupool */
 
-static struct cpupool *cpupool_list;     /* linked list, sorted by poolid */
+static LIST_HEAD(cpupool_list);          /* linked list, sorted by poolid */
 
 static int cpupool_moving_cpu = -1;
 static struct cpupool *cpupool_cpu_moving = NULL;
@@ -189,15 +187,15 @@ static struct cpupool *alloc_cpupool_struct(void)
  */
 static struct cpupool *__cpupool_find_by_id(unsigned int id, bool exact)
 {
-    struct cpupool **q;
+    struct cpupool *q;
 
     ASSERT(spin_is_locked(&cpupool_lock));
 
-    for_each_cpupool(q)
-        if ( (*q)->cpupool_id >= id )
-            break;
+    list_for_each_entry(q, &cpupool_list, list)
+        if ( q->cpupool_id == id || (!exact && q->cpupool_id > id) )
+            return q;
 
-    return (!exact || (*q == NULL) || ((*q)->cpupool_id == id)) ? *q : NULL;
+    return NULL;
 }
 
 static struct cpupool *cpupool_find_by_id(unsigned int poolid)
@@ -246,8 +244,7 @@ static struct cpupool *cpupool_create(
     unsigned int poolid, unsigned int sched_id, int *perr)
 {
     struct cpupool *c;
-    struct cpupool **q;
-    unsigned int last = 0;
+    struct cpupool *q;
 
     *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
@@ -260,23 +257,42 @@ static struct cpupool *cpupool_create(
 
     spin_lock(&cpupool_lock);
 
-    for_each_cpupool(q)
+    if ( poolid != CPUPOOLID_NONE )
     {
-        last = (*q)->cpupool_id;
-        if ( (poolid != CPUPOOLID_NONE) && (last >= poolid) )
-            break;
+        q = __cpupool_find_by_id(poolid, false);
+        if ( !q )
+            list_add_tail(&c->list, &cpupool_list);
+        else
+        {
+            list_add_tail(&c->list, &q->list);
+            if ( q->cpupool_id == poolid )
+            {
+                *perr = -EEXIST;
+                goto err;
+            }
+        }
+
+        c->cpupool_id = poolid;
     }
-    if ( *q != NULL )
+    else
     {
-        if ( (*q)->cpupool_id == poolid )
+        /* Cpupool 0 is created with specified id at boot and never removed. */
+        ASSERT(!list_empty(&cpupool_list));
+
+        q = list_last_entry(&cpupool_list, struct cpupool, list);
+        /* In case of wrap search for first free id. */
+        if ( q->cpupool_id == CPUPOOLID_NONE - 1 )
         {
-            *perr = -EEXIST;
-            goto err;
+            list_for_each_entry(q, &cpupool_list, list)
+                if ( q->cpupool_id + 1 != list_next_entry(q, list)->cpupool_id )
+                    break;
         }
-        c->next = *q;
+
+        list_add(&c->list, &q->list);
+
+        c->cpupool_id = q->cpupool_id + 1;
     }
 
-    c->cpupool_id = (poolid == CPUPOOLID_NONE) ? (last + 1) : poolid;
     if ( poolid == 0 )
     {
         c->sched = scheduler_get_default();
@@ -291,8 +307,6 @@ static struct cpupool *cpupool_create(
     c->gran = opt_sched_granularity;
     c->sched_gran = sched_granularity;
 
-    *q = c;
-
     spin_unlock(&cpupool_lock);
 
     debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
@@ -302,6 +316,8 @@ static struct cpupool *cpupool_create(
     return c;
 
  err:
+    list_del(&c->list);
+
     spin_unlock(&cpupool_lock);
     free_cpupool_struct(c);
     return NULL;
@@ -312,27 +328,19 @@ static struct cpupool *cpupool_create(
  * possible failures:
  * - pool still in use
  * - cpus still assigned to pool
- * - pool not in list
  */
 static int cpupool_destroy(struct cpupool *c)
 {
-    struct cpupool **q;
-
     spin_lock(&cpupool_lock);
-    for_each_cpupool(q)
-        if ( *q == c )
-            break;
-    if ( *q != c )
-    {
-        spin_unlock(&cpupool_lock);
-        return -ENOENT;
-    }
+
     if ( (c->n_dom != 0) || cpumask_weight(c->cpu_valid) )
     {
         spin_unlock(&cpupool_lock);
         return -EBUSY;
     }
-    *q = c->next;
+
+    list_del(&c->list);
+
     spin_unlock(&cpupool_lock);
 
     cpupool_put(c);
@@ -732,17 +740,17 @@ static int cpupool_cpu_remove_prologue(unsigned int cpu)
  */
 static void cpupool_cpu_remove_forced(unsigned int cpu)
 {
-    struct cpupool **c;
+    struct cpupool *c;
     int ret;
     unsigned int master_cpu = sched_get_resource_cpu(cpu);
 
-    for_each_cpupool ( c )
+    list_for_each_entry(c, &cpupool_list, list)
     {
-        if ( cpumask_test_cpu(master_cpu, (*c)->cpu_valid) )
+        if ( cpumask_test_cpu(master_cpu, c->cpu_valid) )
         {
-            ret = cpupool_unassign_cpu_start(*c, master_cpu);
+            ret = cpupool_unassign_cpu_start(c, master_cpu);
             BUG_ON(ret);
-            ret = cpupool_unassign_cpu_finish(*c);
+            ret = cpupool_unassign_cpu_finish(c);
             BUG_ON(ret);
         }
     }
@@ -929,7 +937,7 @@ const cpumask_t *cpupool_valid_cpus(const struct cpupool *pool)
 void dump_runq(unsigned char key)
 {
     s_time_t         now = NOW();
-    struct cpupool **c;
+    struct cpupool *c;
 
     spin_lock(&cpupool_lock);
 
@@ -944,12 +952,12 @@ void dump_runq(unsigned char key)
         schedule_dump(NULL);
     }
 
-    for_each_cpupool(c)
+    list_for_each_entry(c, &cpupool_list, list)
     {
-        printk("Cpupool %u:\n", (*c)->cpupool_id);
-        printk("Cpus: %*pbl\n", CPUMASK_PR((*c)->cpu_valid));
-        sched_gran_print((*c)->gran, cpupool_get_granularity(*c));
-        schedule_dump(*c);
+        printk("Cpupool %u:\n", c->cpupool_id);
+        printk("Cpus: %*pbl\n", CPUMASK_PR(c->cpu_valid));
+        sched_gran_print(c->gran, cpupool_get_granularity(c));
+        schedule_dump(c);
     }
 
     spin_unlock(&cpupool_lock);
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index e69d9be1e8..6953cefa6e 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -8,8 +8,9 @@
 #ifndef __XEN_SCHED_IF_H__
 #define __XEN_SCHED_IF_H__
 
-#include <xen/percpu.h>
 #include <xen/err.h>
+#include <xen/list.h>
+#include <xen/percpu.h>
 #include <xen/rcupdate.h>
 
 /* cpus currently in no cpupool */
@@ -510,6 +511,7 @@ struct cpupool
     unsigned int     n_dom;
     cpumask_var_t    cpu_valid;      /* all cpus assigned to pool */
     cpumask_var_t    res_valid;      /* all scheduling resources of pool */
+    struct list_head list;
     struct cpupool   *next;
     struct scheduler *sched;
     atomic_t         refcnt;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:01:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:01:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47519.84091 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUN-0006qE-El; Tue, 08 Dec 2020 15:01:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47519.84091; Tue, 08 Dec 2020 15:01:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUN-0006q6-Bp; Tue, 08 Dec 2020 15:01:15 +0000
Received: by outflank-mailman (input) for mailman id 47519;
 Tue, 08 Dec 2020 15:01:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUL-0006py-QJ
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUL-00017g-PX
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUL-0002XN-Nv
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=setJJ+C+bByKSmXXgclMaOVLzG9eZhkzzu3BMm3ZjNc=; b=h4n01qjMJwhNl9mTKax3TQGyqK
	pPS5Kb9W1RcuVHG4PG01wASn/Vu+sJ6ZQBCQvHrRloQ5XbbS7/RmeMJdfORtmb/NGM43xTwvVUORq
	Z72b59XvKhCbHTHWrjh+IhG1kuTknTNkGd25sf8df3pHwgZpxQRpQq8Br89I5gkhVTDo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: use ERR_PTR() for returning error cause from cpupool_create()
Message-Id: <E1kmeUL-0002XN-Nv@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:01:13 +0000

commit 841f660b16b7e5ab9c6100d665f276074735e04c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Mon Dec 7 16:19:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Dec 7 16:19:17 2020 +0100

    xen/cpupool: use ERR_PTR() for returning error cause from cpupool_create()
    
    Instead of a pointer to an error variable as parameter just use
    ERR_PTR() to return the cause of an error in cpupool_create().
    
    This propagates to scheduler_alloc(), too.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c    | 13 ++++++-------
 xen/common/sched/cpupool.c | 38 ++++++++++++++++++++------------------
 xen/common/sched/private.h |  2 +-
 3 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 6063f6d9ea..a429fc7640 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -3233,26 +3233,25 @@ struct scheduler *scheduler_get_default(void)
     return &ops;
 }
 
-struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr)
+struct scheduler *scheduler_alloc(unsigned int sched_id)
 {
     int i;
+    int ret;
     struct scheduler *sched;
 
     for ( i = 0; i < NUM_SCHEDULERS; i++ )
         if ( schedulers[i] && schedulers[i]->sched_id == sched_id )
             goto found;
-    *perr = -ENOENT;
-    return NULL;
+    return ERR_PTR(-ENOENT);
 
  found:
-    *perr = -ENOMEM;
     if ( (sched = xmalloc(struct scheduler)) == NULL )
-        return NULL;
+        return ERR_PTR(-ENOMEM);
     memcpy(sched, schedulers[i], sizeof(*sched));
-    if ( (*perr = sched_init(sched)) != 0 )
+    if ( (ret = sched_init(sched)) != 0 )
     {
         xfree(sched);
-        sched = NULL;
+        sched = ERR_PTR(ret);
     }
 
     return sched;
diff --git a/xen/common/sched/cpupool.c b/xen/common/sched/cpupool.c
index 714cd47ae9..0db7d77219 100644
--- a/xen/common/sched/cpupool.c
+++ b/xen/common/sched/cpupool.c
@@ -240,15 +240,15 @@ void cpupool_put(struct cpupool *pool)
  * - poolid already used
  * - unknown scheduler
  */
-static struct cpupool *cpupool_create(
-    unsigned int poolid, unsigned int sched_id, int *perr)
+static struct cpupool *cpupool_create(unsigned int poolid,
+                                      unsigned int sched_id)
 {
     struct cpupool *c;
     struct cpupool *q;
+    int ret;
 
-    *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
-        return NULL;
+        return ERR_PTR(-ENOMEM);
 
     /* One reference for caller, one reference for cpupool_destroy(). */
     atomic_set(&c->refcnt, 2);
@@ -267,7 +267,7 @@ static struct cpupool *cpupool_create(
             list_add_tail(&c->list, &q->list);
             if ( q->cpupool_id == poolid )
             {
-                *perr = -EEXIST;
+                ret = -EEXIST;
                 goto err;
             }
         }
@@ -294,15 +294,15 @@ static struct cpupool *cpupool_create(
     }
 
     if ( poolid == 0 )
-    {
         c->sched = scheduler_get_default();
-    }
     else
+        c->sched = scheduler_alloc(sched_id);
+    if ( IS_ERR(c->sched) )
     {
-        c->sched = scheduler_alloc(sched_id, perr);
-        if ( c->sched == NULL )
-            goto err;
+        ret = PTR_ERR(c->sched);
+        goto err;
     }
+
     c->sched->cpupool = c;
     c->gran = opt_sched_granularity;
     c->sched_gran = sched_granularity;
@@ -312,15 +312,16 @@ static struct cpupool *cpupool_create(
     debugtrace_printk("Created cpupool %u with scheduler %s (%s)\n",
                       c->cpupool_id, c->sched->name, c->sched->opt_name);
 
-    *perr = 0;
     return c;
 
  err:
     list_del(&c->list);
 
     spin_unlock(&cpupool_lock);
+
     free_cpupool_struct(c);
-    return NULL;
+
+    return ERR_PTR(ret);
 }
 /*
  * destroys the given cpupool
@@ -767,7 +768,7 @@ static void cpupool_cpu_remove_forced(unsigned int cpu)
  */
 int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 {
-    int ret;
+    int ret = 0;
     struct cpupool *c;
 
     switch ( op->op )
@@ -779,8 +780,10 @@ int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op)
 
         poolid = (op->cpupool_id == XEN_SYSCTL_CPUPOOL_PAR_ANY) ?
             CPUPOOLID_NONE: op->cpupool_id;
-        c = cpupool_create(poolid, op->sched_id, &ret);
-        if ( c != NULL )
+        c = cpupool_create(poolid, op->sched_id);
+        if ( IS_ERR(c) )
+            ret = PTR_ERR(c);
+        else
         {
             op->cpupool_id = c->cpupool_id;
             cpupool_put(c);
@@ -1003,12 +1006,11 @@ static struct notifier_block cpu_nfb = {
 static int __init cpupool_init(void)
 {
     unsigned int cpu;
-    int err;
 
     cpupool_gran_init();
 
-    cpupool0 = cpupool_create(0, 0, &err);
-    BUG_ON(cpupool0 == NULL);
+    cpupool0 = cpupool_create(0, 0);
+    BUG_ON(IS_ERR(cpupool0));
     cpupool_put(cpupool0);
     register_cpu_notifier(&cpu_nfb);
 
diff --git a/xen/common/sched/private.h b/xen/common/sched/private.h
index 6953cefa6e..92d0d49610 100644
--- a/xen/common/sched/private.h
+++ b/xen/common/sched/private.h
@@ -597,7 +597,7 @@ void sched_rm_cpu(unsigned int cpu);
 const cpumask_t *sched_get_opt_cpumask(enum sched_gran opt, unsigned int cpu);
 void schedule_dump(struct cpupool *c);
 struct scheduler *scheduler_get_default(void);
-struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr);
+struct scheduler *scheduler_alloc(unsigned int sched_id);
 void scheduler_free(struct scheduler *sched);
 int cpu_disable_scheduler(unsigned int cpu);
 int schedule_cpu_add(unsigned int cpu, struct cpupool *c);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:01:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:01:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47521.84095 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUX-0006rO-GG; Tue, 08 Dec 2020 15:01:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47521.84095; Tue, 08 Dec 2020 15:01:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUX-0006rG-DT; Tue, 08 Dec 2020 15:01:25 +0000
Received: by outflank-mailman (input) for mailman id 47521;
 Tue, 08 Dec 2020 15:01:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUV-0006r6-UW
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUV-00018R-Sw
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUV-0002YQ-S8
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6gqUFLtt8fHDGLYw9oBGr+TzCBh6tYOlDR5zA/dORsM=; b=nB3D7pjtiSvGQbWkuQ06nf0NZe
	M9EIsj+opOLGdtNAGBKrtNiAltZsZef/d96K4bJHQDuDq4gAD3mNzUTmlmSH5ZQBs3nTW9nRxpdQQ
	WyN1KwwTufkMU+2Us6XOivpY+2JotD3WANU2XLUegsJHHAL6609Ft1B8RpKOkZsEYxno=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs: fix documentation about default scheduler
Message-Id: <E1kmeUV-0002YQ-S8@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:01:23 +0000

commit 881966dc3b420369b4b39e6586531f58562d88d8
Author:     Roger Pau Monne <roger.pau@citrix.com>
AuthorDate: Tue Nov 17 10:32:58 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Mon Dec 7 15:44:52 2020 +0000

    docs: fix documentation about default scheduler
    
    Fix the command line document to account for the default scheduler in
    Kconfig being credit2 now, and the fact that it's selectable at build
    time and thus different builds could end up with different default
    schedulers.
    
    Fixes: dafd936dddbd ('Make credit2 the default scheduler')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/misc/xen-command-line.pandoc | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index f7db2b64aa..1cb1aee5ed 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -1886,9 +1886,11 @@ with read and write permissions.
 ### sched
 > `= credit | credit2 | arinc653 | rtds | null`
 
-> Default: `sched=credit`
+> Default: `sched=credit2`
 
-Choose the default scheduler.
+Choose the default scheduler. Note the default scheduler is selectable via
+Kconfig and depends on enabled schedulers. Check
+`CONFIG_SCHED_DEFAULT` to see which scheduler is the default.
 
 ### sched_credit2_max_cpus_runqueue
 > `= <integer>`
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 08 15:01:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 08 Dec 2020 15:01:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47522.84100 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUh-0006sb-I4; Tue, 08 Dec 2020 15:01:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47522.84100; Tue, 08 Dec 2020 15:01:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmeUh-0006sR-Ew; Tue, 08 Dec 2020 15:01:35 +0000
Received: by outflank-mailman (input) for mailman id 47522;
 Tue, 08 Dec 2020 15:01:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUg-0006sH-0c
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUf-00018b-W3
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmeUf-0002ZC-VN
 for xen-changelog@lists.xenproject.org; Tue, 08 Dec 2020 15:01:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=deHCsH01Avmy0Ck9xJZ8OOrnylVEjGMGTSEsxerCOlA=; b=ibjmjuZRMs2iFQr6uuImLFAIx0
	1RZTo/nU4uuNzEFcxnUf326iipcGv0ZX2aFgKe6UIBkbwTIuhhQ/CD2Xp1F51rUDFYSbKp4FkICgm
	IxnWJXtt802LVEMxjURR+EG/7pzowtKUAkgla1NRrQE7KX9RIJooi075jMZ0Q2Ne0t2I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs: remove stale README.incompatibilities
Message-Id: <E1kmeUf-0002ZC-VN@xenbits.xenproject.org>
Date: Tue, 08 Dec 2020 15:01:33 +0000

commit 4b0e0db86194b5e9e18c9f2c10b3910f3394c56f
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Sep 9 12:52:13 2020 +0200
Commit:     Wei Liu <wl@xen.org>
CommitDate: Mon Dec 7 15:50:31 2020 +0000

    docs: remove stale README.incompatibilities
    
    It mentions just stale and obsolete distributions.
    They are not suitable to build current Xen, since a couple of years.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/examples/Makefile                 |  1 -
 tools/examples/README.incompatibilities | 38 ---------------------------------
 2 files changed, 39 deletions(-)

diff --git a/tools/examples/Makefile b/tools/examples/Makefile
index f86ed3a271..2a6c5444d4 100644
--- a/tools/examples/Makefile
+++ b/tools/examples/Makefile
@@ -3,7 +3,6 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 # Xen configuration dir and configs to go there.
 XEN_READMES = README
-XEN_READMES += README.incompatibilities
 
 XEN_CONFIGS += xlexample.hvm
 XEN_CONFIGS += xlexample.pvlinux
diff --git a/tools/examples/README.incompatibilities b/tools/examples/README.incompatibilities
deleted file mode 100644
index bb067bd419..0000000000
--- a/tools/examples/README.incompatibilities
+++ /dev/null
@@ -1,38 +0,0 @@
-Command Incompatibilities
-=========================
-
-Known incompatibilities with various commands on various distributions, and
-the workarounds we use.
-
-
-brctl
------
-
-brctl show <bridge> fails on SLES9 SP2.  Workaround is to use brctl show
-without arguments, and grep, though this would be difficult were you to need
-to check for a specific bridge-interface pair, since brctl does not show the 
-bridge name on every line.
-
-
-ifup / ifdown
--------------
-
-SuSE requires an extra parameter to ifup, which is created by calling getcfg
-appropriately.  See xen-network-common.sh for details.
-
-Gentoo doesn't have ifup/ifdown; appropriate alternatives are defined in
-xen-network-common.sh.
-
-
-ip
---
-
-Newer ip commands (from iproute2) do not accept the abbreviated syntax "ip r a
-..." etc.  "ip route add ..." must be used instead.
-
-
-sed
----
-
-\s is not supported in regexps on Debian etch (sed 4.1.2), Ubuntu 4.10.  We
-hand-craft character classes instead.
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 09 00:44:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 09 Dec 2020 00:44:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47920.84776 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmnaN-0008JE-T4; Wed, 09 Dec 2020 00:44:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47920.84776; Wed, 09 Dec 2020 00:44:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmnaN-0008J6-Q6; Wed, 09 Dec 2020 00:44:03 +0000
Received: by outflank-mailman (input) for mailman id 47920;
 Wed, 09 Dec 2020 00:44:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaM-0008J0-M0
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaM-0006AC-KG
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaM-0005Uq-HS
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tVe0q6HPz4nyMAdQqK8F7pafPuA+Q+s67tKb37eYHAE=; b=3bJF0EhXNeumg3zJiKZGhnsAOO
	9bhnvLeDn756+kE2/J7wxBT91tJw0G71hghcc17NFRM/3PgA8NR3J/+m0yoFR72+Xv/y2DPle9bJV
	FiROmZuX/JZgLApsBJtivg6EKKnlLbNPeyKf5DHkF4z9zxQ9Xl/eij8K3YITq+22NrM4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/events: do some cleanups in evtchn_fifo_set_pending()
Message-Id: <E1kmnaM-0005Uq-HS@xenbits.xenproject.org>
Date: Wed, 09 Dec 2020 00:44:02 +0000

commit 0919030638e733993edb8ace762227e440a0cb65
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 8 08:52:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 8 08:52:31 2020 +0100

    xen/events: do some cleanups in evtchn_fifo_set_pending()
    
    evtchn_fifo_set_pending() can be simplified a little bit. Especially
    testing for the fifo control block to exist can be moved out of the
    main if clause of the function enabling to avoid testing the LINKED bit
    twice.
    
    Suggested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/event_fifo.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index a6cca4798d..d508d57219 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -229,29 +229,24 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         goto done;
     }
 
+    /*
+     * Control block not mapped.  The guest must not unmask an
+     * event until the control block is initialized, so we can
+     * just drop the event.
+     */
+    if ( unlikely(!v->evtchn_fifo->control_block) )
+    {
+        printk(XENLOG_G_WARNING
+               "%pv has no FIFO event channel control block\n", v);
+        goto unlock;
+    }
+
     /*
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
-         !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
+         !guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
-        event_word_t *tail_word;
-
-        /*
-         * Control block not mapped.  The guest must not unmask an
-         * event until the control block is initialized, so we can
-         * just drop the event.
-         */
-        if ( unlikely(!v->evtchn_fifo->control_block) )
-        {
-            printk(XENLOG_G_WARNING
-                   "%pv has no FIFO event channel control block\n", v);
-            goto unlock;
-        }
-
-        if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
-            goto unlock;
-
         /*
          * If this event was a tail, the old queue is now empty and
          * its tail must be invalidated to prevent adding an event to
@@ -286,6 +281,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         linked = false;
         if ( q->tail )
         {
+            event_word_t *tail_word;
+
             tail_word = evtchn_fifo_word_from_port(d, q->tail);
             linked = evtchn_fifo_set_link(d, tail_word, port);
         }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 09 00:44:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 09 Dec 2020 00:44:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.47921.84780 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmnaY-0008KW-0D; Wed, 09 Dec 2020 00:44:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 47921.84780; Wed, 09 Dec 2020 00:44:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kmnaX-0008KN-Sr; Wed, 09 Dec 2020 00:44:13 +0000
Received: by outflank-mailman (input) for mailman id 47921;
 Wed, 09 Dec 2020 00:44:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaW-0008KC-OZ
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaW-0006AI-Ni
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kmnaW-0005X8-Mh
 for xen-changelog@lists.xenproject.org; Wed, 09 Dec 2020 00:44:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ROgfO+YOBZjHvgEaAqj6UEedpm93l56yj/BRRgXi7f0=; b=pCUPOt9IQPxws26/CTxHbARx+C
	OsCTx28tLhNDXA0pu4wo7IbgWHBgX+YX7fJZ3LXuEye6zpTGnCbPqOwzpP/LXBU9Ou/f/7hSisr0/
	lMQkDcbuSlLTP8VocHOxIOmh82kgvu/Gk+Zxj3vN8F8LuFzi3IbW9zdAaaBxzBhLX5zs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxenstat: avoid build race
Message-Id: <E1kmnaW-0005X8-Mh@xenbits.xenproject.org>
Date: Wed, 09 Dec 2020 00:44:12 +0000

commit 777e3590f154e6a8af560dd318b9465fa168db20
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 8 08:53:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 8 08:53:18 2020 +0100

    libxenstat: avoid build race
    
    Olaf reported observing
    
    xenstat_qmp.c:26:10: fatal error: _paths.h: No such file or directory
    .../tools/libs/stat/../../../tools/Rules.mk:153: xenstat_qmp.opic] Error 1
    
    Obviously _paths.h, when included by any of the sources, needs to be
    created in advance of compiling any of them, not just when compiling
    into non-PIC objects.
    
    Reported-by: Olaf Hering <olaf@aepfle.de>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/stat/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/libs/stat/Makefile b/tools/libs/stat/Makefile
index 8353e96946..c99508ae6b 100644
--- a/tools/libs/stat/Makefile
+++ b/tools/libs/stat/Makefile
@@ -30,7 +30,7 @@ APPEND_LDFLAGS += $(LDLIBS-y)
 
 include $(XEN_ROOT)/tools/libs/libs.mk
 
-$(LIB_OBJS): _paths.h
+$(LIB_OBJS) $(PIC_OBJS): _paths.h
 
 PYLIB=bindings/swig/python/_xenstat.so
 PYMOD=bindings/swig/python/xenstat.py
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 11 10:55:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 11 Dec 2020 10:55:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.50401.89047 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kng4p-0002Ni-5y; Fri, 11 Dec 2020 10:55:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 50401.89047; Fri, 11 Dec 2020 10:55:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kng4p-0002Na-2w; Fri, 11 Dec 2020 10:55:07 +0000
Received: by outflank-mailman (input) for mailman id 50401;
 Fri, 11 Dec 2020 10:55:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4o-0002NV-1u
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4n-00030R-Tq
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4n-0008Gg-SI
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6PY2w4Y2ilAsQsC0iys3oqyT2sOfS1n7j9/cggHIoec=; b=unmJrzGe2ZjEfpYUZsseTMiEqL
	5tDTdF+xt25miv3rVluJyX/6SN6Ni65JsuwSsD0Tzpv99jQIEcgvYKOTmh0K7t7/0BX/frBn8qC9D
	raLG+LJ3pTlpacrkYTUHCmPTbM15d5+iO8G0qQuZwUf4oAvWOwuVymDDP9+XbWS35B+Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] evtchn: convert vIRQ lock to an r/w one
Message-Id: <E1kng4n-0008Gg-SI@xenbits.xenproject.org>
Date: Fri, 11 Dec 2020 10:55:05 +0000

commit a69583cb50ec07c114cff97f8f902258d6f175d1
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 11 11:52:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 11 11:52:35 2020 +0100

    evtchn: convert vIRQ lock to an r/w one
    
    There's no need to serialize all sending of vIRQ-s; all that's needed
    is serialization against the closing of the respective event channels
    (so far by means of a barrier). To facilitate the conversion, switch to
    an ordinary write locked region in evtchn_close().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/domain.c        |  2 +-
 xen/common/event_channel.c | 25 +++++++++++++++++--------
 xen/include/xen/sched.h    |  2 +-
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index f748806a45..5ec48c3e19 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -160,7 +160,7 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int vcpu_id)
     v->vcpu_id = vcpu_id;
     v->dirty_cpu = VCPU_CPU_CLEAN;
 
-    spin_lock_init(&v->virq_lock);
+    rwlock_init(&v->virq_lock);
 
     tasklet_init(&v->continue_hypercall_tasklet, NULL, NULL);
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 59f95f2eb2..4a48094356 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -470,6 +470,13 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     evtchn_write_unlock(chn);
 
     bind->port = port;
+    /*
+     * If by any, the update of virq_to_evtchn[] would need guarding by
+     * virq_lock, but since this is the last action here, there's no strict
+     * need to acquire the lock. Hence holding event_lock isn't helpful
+     * anymore at this point, but utilize that its unlocking acts as the
+     * otherwise necessary smp_wmb() here.
+     */
     write_atomic(&v->virq_to_evtchn[virq], port);
 
  out:
@@ -656,10 +663,12 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     case ECS_VIRQ:
         for_each_vcpu ( d1, v )
         {
-            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) != port1 )
-                continue;
-            write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
-            spin_barrier(&v->virq_lock);
+            unsigned long flags;
+
+            write_lock_irqsave(&v->virq_lock, flags);
+            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) == port1 )
+                write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
+            write_unlock_irqrestore(&v->virq_lock, flags);
         }
         break;
 
@@ -809,7 +818,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     ASSERT(!virq_is_global(virq));
 
-    spin_lock_irqsave(&v->virq_lock, flags);
+    read_lock_irqsave(&v->virq_lock, flags);
 
     port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
@@ -824,7 +833,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
     }
 
  out:
-    spin_unlock_irqrestore(&v->virq_lock, flags);
+    read_unlock_irqrestore(&v->virq_lock, flags);
 }
 
 void send_guest_global_virq(struct domain *d, uint32_t virq)
@@ -843,7 +852,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
     if ( unlikely(v == NULL) )
         return;
 
-    spin_lock_irqsave(&v->virq_lock, flags);
+    read_lock_irqsave(&v->virq_lock, flags);
 
     port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
@@ -857,7 +866,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
     }
 
  out:
-    spin_unlock_irqrestore(&v->virq_lock, flags);
+    read_unlock_irqrestore(&v->virq_lock, flags);
 }
 
 void send_guest_pirq(struct domain *d, const struct pirq *pirq)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 31abbe7a99..faf5fda36f 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -239,7 +239,7 @@ struct vcpu
 
     /* IRQ-safe virq_lock protects against delivering VIRQ to stale evtchn. */
     evtchn_port_t    virq_to_evtchn[NR_VIRQS];
-    spinlock_t       virq_lock;
+    rwlock_t         virq_lock;
 
     /* Tasklet for continue_hypercall_on_cpu(). */
     struct tasklet   continue_hypercall_tasklet;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 11 10:55:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 11 Dec 2020 10:55:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.50402.89051 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kng4z-0002OY-7m; Fri, 11 Dec 2020 10:55:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 50402.89051; Fri, 11 Dec 2020 10:55:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kng4z-0002OO-4Y; Fri, 11 Dec 2020 10:55:17 +0000
Received: by outflank-mailman (input) for mailman id 50402;
 Fri, 11 Dec 2020 10:55:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4y-0002OD-3g
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4y-00030U-17
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kng4x-0008HK-WD
 for xen-changelog@lists.xenproject.org; Fri, 11 Dec 2020 10:55:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6hR+XWUBmHx3tPRnl7ffu9x8QHqxQG9EcSRS7xMH91o=; b=J2yIAU6W1rWkYW9pUtMxLug69E
	tfYvuIlg+vIcvQTnH8aD8yA6/tQbtVTF2tCx0DJeIoH6kW4AbvXslTpnw3dt9whe0AvSPp9bAj9IM
	QW0ItG4tgZThPQrmd+BHGq3MQ7Yt9/OQrs8CP4dJlVn4LBFEeIIpPc+ravHdNuQ7geLk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen: fix build when $(obj-y) consists of just blanks
Message-Id: <E1kng4x-0008HK-WD@xenbits.xenproject.org>
Date: Fri, 11 Dec 2020 10:55:15 +0000

commit 8e0fe4fe5fd89d80a362d8a9a46726aded3b49c4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 11 11:53:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 11 11:53:24 2020 +0100

    xen: fix build when $(obj-y) consists of just blanks
    
    This case can occur when combining empty lists
    
    obj-y :=
    ...
    obj-y += $(empty)
    
    or
    
    obj-y := $(empty) $(empty)
    
    where (only) blanks would accumulate. This was only a latent issue until
    now, but would become an active issue for Arm once lib/ gets populated
    with all respective objects going into the to be introduced lib.a.
    
    Also address a related issue at this occasion: When an empty built_in.o
    gets created, .built_in.o.d will have its dependencies recorded. If, on
    a subsequent incremental build, an actual constituent of built_in.o
    appeared, the $(filter-out ) would leave these recorded dependencies in
    place. But of course the linker won't know what to do with C header
    files. (The apparent alternative of avoiding to pass $(c_flags) or
    $(a_flags) would not be reliable afaict, as among these flags there may
    be some affecting information conveyed via the object file to the
    linker. The linker, finding inconsistent flags across object files, may
    then error out.) Using just $(obj-y) won't work either: It breaks when
    the same object file is listed more than once.
    
    Reported-by: Julien Grall <julien@xen.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
---
 xen/Rules.mk | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index 333e19bec3..d5e5eb33de 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -130,13 +130,13 @@ c_flags += $(CFLAGS-y)
 a_flags += $(CFLAGS-y) $(AFLAGS-y)
 
 built_in.o: $(obj-y) $(extra-y)
-ifeq ($(obj-y),)
+ifeq ($(strip $(obj-y)),)
 	$(CC) $(c_flags) -c -x c /dev/null -o $@
 else
 ifeq ($(CONFIG_LTO),y)
-	$(LD_LTO) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD_LTO) -r -o $@ $(filter $(obj-y),$^)
 else
-	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter $(obj-y),$^)
 endif
 endif
 
@@ -145,10 +145,10 @@ targets += $(filter-out $(subdir-obj-y), $(obj-y)) $(extra-y)
 targets += $(MAKECMDGOALS)
 
 built_in_bin.o: $(obj-bin-y) $(extra-y)
-ifeq ($(obj-bin-y),)
+ifeq ($(strip $(obj-bin-y)),)
 	$(CC) $(a_flags) -c -x assembler /dev/null -o $@
 else
-	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter $(obj-bin-y),$^)
 endif
 
 # Force execution of pattern rules (for which PHONY cannot be directly used).
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Sat Dec 12 01:55:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 12 Dec 2020 01:55:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.51008.89909 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1knu7k-0005HX-E4; Sat, 12 Dec 2020 01:55:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 51008.89909; Sat, 12 Dec 2020 01:55:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1knu7k-0005HO-AP; Sat, 12 Dec 2020 01:55:04 +0000
Received: by outflank-mailman (input) for mailman id 51008;
 Sat, 12 Dec 2020 01:55:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7i-0005HJ-W9
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7i-0005Zb-Pr
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7i-0001zS-Me
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kmq/t8u+XnqwyKCyLc7D1jw/MIravfHww+YL87VGzmI=; b=WMbOck4SEhQC8FqYHcQoYPwZni
	pk7kM0Dmyuh7Rt7l7MugTvilnV1ZCB5gHiHupCCpOGWPWO9JDbxZo94R458zKa/VaDh4gCMvE5bkt
	01YoFH/3n+BiZY6zJE5L9Tv9VVdkLQdfA/7VLvF0kAG57GdSIVBrB5i/jZ2eATmg8wqU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] evtchn: convert vIRQ lock to an r/w one
Message-Id: <E1knu7i-0001zS-Me@xenbits.xenproject.org>
Date: Sat, 12 Dec 2020 01:55:02 +0000

commit a69583cb50ec07c114cff97f8f902258d6f175d1
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 11 11:52:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 11 11:52:35 2020 +0100

    evtchn: convert vIRQ lock to an r/w one
    
    There's no need to serialize all sending of vIRQ-s; all that's needed
    is serialization against the closing of the respective event channels
    (so far by means of a barrier). To facilitate the conversion, switch to
    an ordinary write locked region in evtchn_close().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/domain.c        |  2 +-
 xen/common/event_channel.c | 25 +++++++++++++++++--------
 xen/include/xen/sched.h    |  2 +-
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index f748806a45..5ec48c3e19 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -160,7 +160,7 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int vcpu_id)
     v->vcpu_id = vcpu_id;
     v->dirty_cpu = VCPU_CPU_CLEAN;
 
-    spin_lock_init(&v->virq_lock);
+    rwlock_init(&v->virq_lock);
 
     tasklet_init(&v->continue_hypercall_tasklet, NULL, NULL);
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 59f95f2eb2..4a48094356 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -470,6 +470,13 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
     evtchn_write_unlock(chn);
 
     bind->port = port;
+    /*
+     * If by any, the update of virq_to_evtchn[] would need guarding by
+     * virq_lock, but since this is the last action here, there's no strict
+     * need to acquire the lock. Hence holding event_lock isn't helpful
+     * anymore at this point, but utilize that its unlocking acts as the
+     * otherwise necessary smp_wmb() here.
+     */
     write_atomic(&v->virq_to_evtchn[virq], port);
 
  out:
@@ -656,10 +663,12 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
     case ECS_VIRQ:
         for_each_vcpu ( d1, v )
         {
-            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) != port1 )
-                continue;
-            write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
-            spin_barrier(&v->virq_lock);
+            unsigned long flags;
+
+            write_lock_irqsave(&v->virq_lock, flags);
+            if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) == port1 )
+                write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
+            write_unlock_irqrestore(&v->virq_lock, flags);
         }
         break;
 
@@ -809,7 +818,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
 
     ASSERT(!virq_is_global(virq));
 
-    spin_lock_irqsave(&v->virq_lock, flags);
+    read_lock_irqsave(&v->virq_lock, flags);
 
     port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
@@ -824,7 +833,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
     }
 
  out:
-    spin_unlock_irqrestore(&v->virq_lock, flags);
+    read_unlock_irqrestore(&v->virq_lock, flags);
 }
 
 void send_guest_global_virq(struct domain *d, uint32_t virq)
@@ -843,7 +852,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
     if ( unlikely(v == NULL) )
         return;
 
-    spin_lock_irqsave(&v->virq_lock, flags);
+    read_lock_irqsave(&v->virq_lock, flags);
 
     port = read_atomic(&v->virq_to_evtchn[virq]);
     if ( unlikely(port == 0) )
@@ -857,7 +866,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
     }
 
  out:
-    spin_unlock_irqrestore(&v->virq_lock, flags);
+    read_unlock_irqrestore(&v->virq_lock, flags);
 }
 
 void send_guest_pirq(struct domain *d, const struct pirq *pirq)
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 31abbe7a99..faf5fda36f 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -239,7 +239,7 @@ struct vcpu
 
     /* IRQ-safe virq_lock protects against delivering VIRQ to stale evtchn. */
     evtchn_port_t    virq_to_evtchn[NR_VIRQS];
-    spinlock_t       virq_lock;
+    rwlock_t         virq_lock;
 
     /* Tasklet for continue_hypercall_on_cpu(). */
     struct tasklet   continue_hypercall_tasklet;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 12 01:55:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 12 Dec 2020 01:55:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.51009.89913 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1knu7t-0005I7-F2; Sat, 12 Dec 2020 01:55:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 51009.89913; Sat, 12 Dec 2020 01:55:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1knu7t-0005Hz-C4; Sat, 12 Dec 2020 01:55:13 +0000
Received: by outflank-mailman (input) for mailman id 51009;
 Sat, 12 Dec 2020 01:55:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7s-0005Hu-Uq
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7s-0005Ze-Td
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1knu7s-000202-SW
 for xen-changelog@lists.xenproject.org; Sat, 12 Dec 2020 01:55:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4EbN7MmUzUfCnxAKsyTJdQCg0DCyTgO77+O33aQWAJQ=; b=vXtBkvDXEMWcuwWr2BeWnRK4R4
	sJDu2zNK8wSc+D/Jkh9gYCT3LJOfx410zO4MG0uBWGb6+gz5RRVA2cAwLm9yY2phKjV/hXuzYJm5C
	Emw8d29JF8RcqzgznaIE6n/LxAeBIRKQsnGEokSD4P++ObR8B85tpCOVlk9XtPTCx9IU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen: fix build when $(obj-y) consists of just blanks
Message-Id: <E1knu7s-000202-SW@xenbits.xenproject.org>
Date: Sat, 12 Dec 2020 01:55:12 +0000

commit 8e0fe4fe5fd89d80a362d8a9a46726aded3b49c4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 11 11:53:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 11 11:53:24 2020 +0100

    xen: fix build when $(obj-y) consists of just blanks
    
    This case can occur when combining empty lists
    
    obj-y :=
    ...
    obj-y += $(empty)
    
    or
    
    obj-y := $(empty) $(empty)
    
    where (only) blanks would accumulate. This was only a latent issue until
    now, but would become an active issue for Arm once lib/ gets populated
    with all respective objects going into the to be introduced lib.a.
    
    Also address a related issue at this occasion: When an empty built_in.o
    gets created, .built_in.o.d will have its dependencies recorded. If, on
    a subsequent incremental build, an actual constituent of built_in.o
    appeared, the $(filter-out ) would leave these recorded dependencies in
    place. But of course the linker won't know what to do with C header
    files. (The apparent alternative of avoiding to pass $(c_flags) or
    $(a_flags) would not be reliable afaict, as among these flags there may
    be some affecting information conveyed via the object file to the
    linker. The linker, finding inconsistent flags across object files, may
    then error out.) Using just $(obj-y) won't work either: It breaks when
    the same object file is listed more than once.
    
    Reported-by: Julien Grall <julien@xen.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
---
 xen/Rules.mk | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index 333e19bec3..d5e5eb33de 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -130,13 +130,13 @@ c_flags += $(CFLAGS-y)
 a_flags += $(CFLAGS-y) $(AFLAGS-y)
 
 built_in.o: $(obj-y) $(extra-y)
-ifeq ($(obj-y),)
+ifeq ($(strip $(obj-y)),)
 	$(CC) $(c_flags) -c -x c /dev/null -o $@
 else
 ifeq ($(CONFIG_LTO),y)
-	$(LD_LTO) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD_LTO) -r -o $@ $(filter $(obj-y),$^)
 else
-	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter $(obj-y),$^)
 endif
 endif
 
@@ -145,10 +145,10 @@ targets += $(filter-out $(subdir-obj-y), $(obj-y)) $(extra-y)
 targets += $(MAKECMDGOALS)
 
 built_in_bin.o: $(obj-bin-y) $(extra-y)
-ifeq ($(obj-bin-y),)
+ifeq ($(strip $(obj-bin-y)),)
 	$(CC) $(a_flags) -c -x assembler /dev/null -o $@
 else
-	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out $(extra-y),$^)
+	$(LD) $(XEN_LDFLAGS) -r -o $@ $(filter $(obj-bin-y),$^)
 endif
 
 # Force execution of pattern rules (for which PHONY cannot be directly used).
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53844.93443 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9r8-0000f3-Qo; Tue, 15 Dec 2020 12:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53844.93443; Tue, 15 Dec 2020 12:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9r8-0000ev-O3; Tue, 15 Dec 2020 12:55:06 +0000
Received: by outflank-mailman (input) for mailman id 53844;
 Tue, 15 Dec 2020 12:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9r7-0000eq-4Q
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9r7-0006Rm-22
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9r6-00032w-Vj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7sP1q9MG4IIbOi1BxWcefSRt5Dl7+xPWIdPn/N1kKR4=; b=7C58OSYqZcTdX7w3J/hQIaFx1i
	VGuaDONki3m3NUPQLjeoPRkFaD4JxFzdasGLAh0+hk9JKkXJKJYq13qW0X1+0lLbBHOqEaZ2RxpKE
	cAcZ+JwMD4vvn2NV24lwbRxwfnljlZ8DuLLPJ62Q5fmJAAw6oNagycvc0pLuOwlKA6Uo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kp9r6-00032w-Vj@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:04 +0000

commit feeafa007b804cdf2406c50a6515ee0a217d3438
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:33:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:33:43 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53847.93448 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rI-0000g7-Sj; Tue, 15 Dec 2020 12:55:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53847.93448; Tue, 15 Dec 2020 12:55:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rI-0000fz-Pd; Tue, 15 Dec 2020 12:55:16 +0000
Received: by outflank-mailman (input) for mailman id 53847;
 Tue, 15 Dec 2020 12:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rH-0000fl-6U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rH-0006Rp-5i
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rH-00033x-4C
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9P/94tEGvC1xfxiVZBNoz+nrog+1dH1NLJvxVqHlbv0=; b=W3wlCdqSdtvcrIA4QRN6NuFfgr
	3FNnUlA1goaBFbi4g7tdKlGAEJeQ0HL5gru7Xqctk3QnRJHGJkKZfUpRNz7UttUREqlOBPf8DMjEn
	15GleTUbDcRSdCsw9toutLTNvvAeekqZrmZ0IE2OZLjf7kDZ2tKybGDzeHj7pppDli7s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kp9rH-00033x-4C@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:15 +0000

commit 705c7d89565fc2f7d06a255a4a76c6642340dbe2
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:35 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4be374d3f..7bf1123da3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -413,7 +413,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -423,7 +424,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -451,14 +452,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -992,7 +994,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1032,7 +1034,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1108,7 +1110,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1247,7 +1249,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1505,7 +1507,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 1df6ad94ab..53aafa1d9b 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -146,7 +146,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53854.93452 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rS-0000j7-VI; Tue, 15 Dec 2020 12:55:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53854.93452; Tue, 15 Dec 2020 12:55:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rS-0000iz-S6; Tue, 15 Dec 2020 12:55:26 +0000
Received: by outflank-mailman (input) for mailman id 53854;
 Tue, 15 Dec 2020 12:55:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rR-0000iU-9X
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rR-0006S0-8i
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rR-000350-7m
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hEohm04vLaDLhRtca5ZYT8S0LGfyHLT5iTp2eWKlqzU=; b=bnLYwY4JbARhkhQUY01u1zwIoh
	Nq0qaUQAVr5CqQy5osGuM5tkQi1gQLhuBKPE23icO+S+X04BUI54sMebBkHxdcVePCGnSJW71wvCk
	E6wBNmwjk5Zwx50yGDNoUbqnsF2Zb2E2GjIMMfBkJOX/RIFcFQC+8rctUGK2nHnbTWeU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kp9rR-000350-7m@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:25 +0000

commit 09a4146bdcf8eea804dd90fee4b9132bdbf69bae
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:37 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 7bf1123da3..3471ce1592 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1261,13 +1261,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1289,7 +1293,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1304,7 +1308,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1313,12 +1324,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53858.93455 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rd-0000ki-1A; Tue, 15 Dec 2020 12:55:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53858.93455; Tue, 15 Dec 2020 12:55:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rc-0000kZ-UO; Tue, 15 Dec 2020 12:55:36 +0000
Received: by outflank-mailman (input) for mailman id 53858;
 Tue, 15 Dec 2020 12:55:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rb-0000kG-Cf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rb-0006ST-Bq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rb-00035r-As
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fShnfD7myMec1VLrBvb2lzO9jqfra+UsJEENLzd4kfA=; b=3/J2PuMCkxBwLnWzZ4BYV9gnL2
	iQjOz8cQPDLcO9IUCijxyY+3aVa9Xv1xpxUCpvmc2dCmxyEwusevIrHxV4vdK+8plIENcub2AEYOl
	wMW/vBEFMM+pY5Afp8U+HMuwV+emFCYntVQ9fxyMvM2bwjwFkSdVu5/Oy9eNHs4McxmI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kp9rb-00035r-As@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:35 +0000

commit 0bfb2101f243b27611ffec2087559d816d591e63
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:40 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:40 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3471ce1592..476e69d658 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -918,11 +918,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -955,7 +950,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -975,6 +969,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -991,18 +988,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53861.93460 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rn-0000mH-2d; Tue, 15 Dec 2020 12:55:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53861.93460; Tue, 15 Dec 2020 12:55:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rm-0000m9-W0; Tue, 15 Dec 2020 12:55:46 +0000
Received: by outflank-mailman (input) for mailman id 53861;
 Tue, 15 Dec 2020 12:55:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rl-0000ls-FP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rl-0006Sd-El
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rl-00036c-Dq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tP3gM35+uzBtKA1gIYGP/RlHDP7FX0Eyw0klsrslquM=; b=JFYH+D4T16U96v4FQI5laKljor
	/eNdB8vdtulAM8oG83cZqJJcbHPhNJdueLNQX1OIBZ5UpfjsvL85bntqqm+Ihm35vHz3m0IvrrZdd
	jEmACJqz27OybIV/cxy+3N0OqhtxIuBgxUni18gJ/lUBA5k16Kbn+ZVA3x3ICbHfyEjY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kp9rl-00036c-Dq@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:45 +0000

commit d3f8c086d23d886e2f5357b096bfefd5c8e5bcc4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:42 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:55:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:55:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53870.93463 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rx-0000oY-5d; Tue, 15 Dec 2020 12:55:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53870.93463; Tue, 15 Dec 2020 12:55:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9rx-0000oJ-1u; Tue, 15 Dec 2020 12:55:57 +0000
Received: by outflank-mailman (input) for mailman id 53870;
 Tue, 15 Dec 2020 12:55:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rv-0000oB-KX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rv-0006Sp-Jk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9rv-00037I-H1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:55:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=41VCO4jTJWeVXgVxDcMERHx689qlas/ZZ+dt1a+yOeg=; b=sRvSS79JtuuGNiCDcJ9loDy/NT
	BaOBU8lB0ThweA5Sf5E+Df/JXLxam4+qYlmM6FyyLVJPDdK4mysGj5KM7KUk5yMOfUFxwHEWp7VAj
	WcORwMIkpyBFyypksVR9b6wy1YFWuKo3adLsAmoOJA4LDqk3jl3kSX3y22IeKXXpjUuE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kp9rv-00037I-H1@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:55:55 +0000

commit fa2307be61df52970e7ee47a6c55124155c173c6
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:45 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  9 ---------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 476e69d658..3d0e7b3917 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1276,8 +1276,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1287,8 +1289,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1297,9 +1301,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1327,6 +1333,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index a2f144f6dd..364ad8ea63 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -372,9 +372,6 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
 	domid = atoi(vec[0]);
 	/* Ignore the gfn, we don't need it. */
 	port = atoi(vec[2]);
@@ -438,9 +435,6 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
 	domid = atoi(vec[0]);
 	tdomid = atoi(vec[1]);
 
@@ -473,9 +467,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53882.93468 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9s7-0000r5-7z; Tue, 15 Dec 2020 12:56:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53882.93468; Tue, 15 Dec 2020 12:56:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9s7-0000qx-4z; Tue, 15 Dec 2020 12:56:07 +0000
Received: by outflank-mailman (input) for mailman id 53882;
 Tue, 15 Dec 2020 12:56:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9s5-0000ql-Nq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9s5-0006Uk-N8
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9s5-00038I-Lv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=uRD+vRLQcPDrsM+Blxv1jodrhxQ86XGiEJg2QPRnbY0=; b=vq42ZJc/0zrujVDDPzEl+GW1cS
	U42+4BDpLEx3Rmb3KwiHddXw4jP7/W8doRnJ0vNW0k9FntkSS33HvN5+gNPpgkEbk2OS0PAj0AOl6
	9gLu6FX+q8dtdErS7h4fWN549aB+Y8W/9U9EPCxI+eIUCjsyWkqKmg8PnskMze3Vi3nI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: rework node removal
Message-Id: <E1kp9s5-00038I-Lv@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:05 +0000

commit 297f209636d89ca5bfe2b91accfdf0dc1b922779
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:48 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3d0e7b3917..c74413bda2 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1080,74 +1080,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1158,11 +1160,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1200,7 +1204,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53888.93472 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sH-0000t8-Af; Tue, 15 Dec 2020 12:56:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53888.93472; Tue, 15 Dec 2020 12:56:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sH-0000sz-6X; Tue, 15 Dec 2020 12:56:17 +0000
Received: by outflank-mailman (input) for mailman id 53888;
 Tue, 15 Dec 2020 12:56:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sF-0000sf-R9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sF-0006Us-QQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sF-000399-PN
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LmcQFETg/WG4JNyq8+TPZNWs/GSdvjsEqgYmVH5xblE=; b=EASAjkqR4kMeWbwV4PfgPy9a+J
	VwdL6H9DrahgCgwGQwlG22kk+aKsl3YPE8HWoMk8HnhiAFJVlhJlMC+GvC/t+UdTqo4uk1H8uhkwk
	h5PBXGiI6AMS9uf/sqLH9wMOyr1Ru5V4osupKg6aPV6M06oB4xWB2OYAcSKE55nEMPq0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kp9sF-000399-PN@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:15 +0000

commit 1e5815697f941d57fbdc81d0e973a00692adfad3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:50 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c74413bda2..b39610c876 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1111,8 +1111,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1124,7 +1124,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1136,6 +1136,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,8 +1166,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53893.93476 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sQ-0000v5-B3; Tue, 15 Dec 2020 12:56:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53893.93476; Tue, 15 Dec 2020 12:56:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sQ-0000ux-83; Tue, 15 Dec 2020 12:56:26 +0000
Received: by outflank-mailman (input) for mailman id 53893;
 Tue, 15 Dec 2020 12:56:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sP-0000us-UC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sP-0006V2-TP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sP-00039z-Sa
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6fz4O6b/m+V7+A2RLreVIM66XWVgjysf8cAC4t3to80=; b=kO9wHREZk3AiyOW/5jN4f+r1fj
	smIN5NrdMfe8LBdhoCzp+l89scdGyA5eML+THLhqrItpNb/MYvNiOgM56LAyfBdTwz9vN142yr8hZ
	PxhfiwVzuIo2AuBmA9k4lyXBsC/llD1NeUcBy9B9p3xKn/E7uaoZ86UCGhK9h7WARNdQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: introduce node_perms structure
Message-Id: <E1kp9sP-00039z-Sa@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:25 +0000

commit 53dabb1fdb30788f9e1826c3543ecf19d37d60d4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:53 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:53 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b39610c876..06e937de66 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -397,14 +397,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -421,7 +421,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -433,12 +433,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -464,23 +465,22 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -527,7 +527,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -573,8 +573,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -750,16 +749,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -938,13 +936,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1221,7 +1219,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1232,13 +1230,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1249,21 +1246,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1536,8 +1533,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53aafa1d9b..a291f15ce7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -106,6 +106,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -117,8 +122,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 364ad8ea63..76bdd46c8d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -650,12 +650,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -676,12 +676,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53897.93480 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sa-0000wr-Cc; Tue, 15 Dec 2020 12:56:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53897.93480; Tue, 15 Dec 2020 12:56:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sa-0000wj-9j; Tue, 15 Dec 2020 12:56:36 +0000
Received: by outflank-mailman (input) for mailman id 53897;
 Tue, 15 Dec 2020 12:56:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sa-0000wd-0r
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sa-0006VQ-09
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sZ-0003Aq-Vd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nKjmEitp11NjhnK9VIEQppZBbTmbIC94UJn+lKNJGHU=; b=vju/9PKT7wIkfcjUJOqoU3lPa2
	PzHmhmDcin9ErsNFBfrcK8vM4l40oQ09KfBFwEVsIIwQ6ArYg1mx7Refw0TSv+/8yM3nNaaMN4FQt
	erw7RpM0K5MWlC12Id3El4nhFDpto6fv4uyXf2GEl719Wnd8oNkBtkYcoM1wvM1UF6wA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kp9sZ-0003Aq-Vd@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:35 +0000

commit 190ddd3403bad28167a070388a904b02b956093c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:56 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index cb8009cb68..2081f20f55 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See https://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 06e937de66..1db9d0cc31 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -464,8 +464,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1238,22 +1238,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a291f15ce7..3f958c29ab 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -162,6 +162,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 76bdd46c8d..e1106d90b6 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -576,6 +579,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -597,6 +653,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53898.93484 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sl-0000yW-G4; Tue, 15 Dec 2020 12:56:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53898.93484; Tue, 15 Dec 2020 12:56:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sl-0000yM-Cs; Tue, 15 Dec 2020 12:56:47 +0000
Received: by outflank-mailman (input) for mailman id 53898;
 Tue, 15 Dec 2020 12:56:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sk-0000y9-44
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sk-0006VY-3J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9sk-0003Bm-2M
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oFt0eIzR4xgKj10WTBxc7qgOdHwXg8IlkxUntF+Zf2I=; b=hv0Bgrph7/CX4nL0AQVHCdlWd6
	nOBjBSLLylMsXCg6QyGzyDfq3JTDJ4don0I3Ok5xmE+Ckf4zfyLezDHMQ2SlG0b9ys9WbEFf/HH57
	SQA4F+7+camoFEY/PDf8qW5OtfGHS9MjGSj4nMTflhIACm/2/GUbZP2s831yvkiD4mj4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kp9sk-0003Bm-2M@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:46 +0000

commit e47f438df3bdffe213b6bd28245504c8c7fe367a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:58 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:58 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1db9d0cc31..ad1903c555 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -354,8 +354,8 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -487,7 +487,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -559,10 +559,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1049,7 +1049,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1071,7 +1071,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1134,7 +1134,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1158,13 +1158,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1230,7 +1231,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1266,6 +1267,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1273,7 +1275,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3f958c29ab..6c21d5bb9a 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,15 +149,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -168,6 +170,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e1106d90b6..cf239c044b 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -202,7 +202,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -240,7 +240,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -401,7 +401,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:56:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:56:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53899.93488 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sv-000117-HY; Tue, 15 Dec 2020 12:56:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53899.93488; Tue, 15 Dec 2020 12:56:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9sv-000110-EX; Tue, 15 Dec 2020 12:56:57 +0000
Received: by outflank-mailman (input) for mailman id 53899;
 Tue, 15 Dec 2020 12:56:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9su-00010s-6o
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9su-0006Ve-66
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9su-0003CT-5N
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:56:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=f0L63oWJhQmgyY0I4HDHgPjmyFQAncPM51xoHpOmgZ4=; b=a9/BoqsVToZl1wrnKHZJEVV24i
	Be/lxpW4GlFEmzD8hab71eVT2IAg2h8frMOPx2ioewEN0tKTnaz7zzKzRAeHo57V/OSN1mL87JRz8
	ZONhRa2BweCoupgbFg+xMEgaOHinzv+eNd/V1nvVDzIlBQXu3P9590Ii8vB2/yV6X2Ig=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kp9su-0003CT-5N@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:56:56 +0000

commit f40d933da4d689ef9b62d7479540ad1be36e0dad
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:06 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:06 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53900.93491 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9t5-00012V-JQ; Tue, 15 Dec 2020 12:57:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53900.93491; Tue, 15 Dec 2020 12:57:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9t5-00012O-GR; Tue, 15 Dec 2020 12:57:07 +0000
Received: by outflank-mailman (input) for mailman id 53900;
 Tue, 15 Dec 2020 12:57:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9t4-00012E-Bp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9t4-0006W6-91
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9t4-0003DG-87
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1y8tX3UfmuWx5boVN2zP3crWuyjkzwhO5wXzAyCbe6M=; b=xEWq3T9T6YuQOoGe8JzDRvz88/
	akW4tu3EDifUPlraN3cDUtPufR/x0mj7OUbQsJi1n+3iVBO3zJ4FpofU9rCg6d/EZaxtneN2gTab1
	rFpEXM1tVp/qW8ALB7EdArPouo7GmiIEE5CnJTRzA4K7wfCS2pnDeB8D0v9/7UUhbFPk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kp9t4-0003DG-87@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:06 +0000

commit 67bfd6cd4b1b44882f2a549a8750e278338436e9
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:08 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53903.93496 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tF-00014H-L8; Tue, 15 Dec 2020 12:57:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53903.93496; Tue, 15 Dec 2020 12:57:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tF-000147-I1; Tue, 15 Dec 2020 12:57:17 +0000
Received: by outflank-mailman (input) for mailman id 53903;
 Tue, 15 Dec 2020 12:57:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tE-00013p-Cq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tE-0006WG-C3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tE-0003E2-B6
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+8c9Q7SBQyd5T/Ro7/PbO9so8XSA0+6TGQ+EGgtMEB4=; b=jQs35L5RLVgHp5YpIwNwFtLEYm
	PD1gpOeLRWorS6Mb2h021xQzTxhAGQzBi4A95SuZ6BGnCUbUwr4+E6zJCkSlP5O6z1J23JkZq1rea
	Lp7yhqNctxucDfQIvYVsB6o3OKgdFrQ/jZcSLYSErc4HWURJuE/+OeyHvlxRWPMx7v7Q=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kp9tE-0003E2-B6@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:16 +0000

commit 0911dfad0fbadee2ffaf1da1a8c596b750fd21d4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:11 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53905.93501 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tP-00016H-OA; Tue, 15 Dec 2020 12:57:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53905.93501; Tue, 15 Dec 2020 12:57:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tP-000169-Jx; Tue, 15 Dec 2020 12:57:27 +0000
Received: by outflank-mailman (input) for mailman id 53905;
 Tue, 15 Dec 2020 12:57:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tO-00015s-G7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tO-0006WO-FL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tO-0003F2-ER
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0H7yZ7moSoZIltZEt4aVeVdDrxeFakUzJoDeSzAHoZ8=; b=NMWuxCo9p5SgsNGqBE5w1f4AfR
	5On4G9Gax2hR0o30BDndIJbgDkHlBdscpHjjIKbZAa83njyUpI3Bo6ae5GWuYnFTdqB0OJZ1V4Uk+
	Yrzcned67ttJ3xjPL1aP76/l8ZG+kutRE7ZIePezEm/dpsI3oYzdQ6R+0SieuqLIDAU4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kp9tO-0003F2-ER@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:26 +0000

commit cf4116c38c0d3ab83cdaac7a23bc8598362c410d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:13 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 7e7824761b..8d0c50bfa4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -286,6 +286,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -335,7 +337,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53914.93504 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tZ-00018X-Qs; Tue, 15 Dec 2020 12:57:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53914.93504; Tue, 15 Dec 2020 12:57:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tZ-00018P-Nr; Tue, 15 Dec 2020 12:57:37 +0000
Received: by outflank-mailman (input) for mailman id 53914;
 Tue, 15 Dec 2020 12:57:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tY-00018C-JS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tY-0006Wr-Ip
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9tY-0003Fg-Hf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BbVTqJNvIALL4URWWijNxUHZTQHAnqnBuVizYKbDu2U=; b=lbfdPRi42og1o660BJuC5BuAmk
	n0/k2g6zM7tJwQABHSUJBM+vBSqVX8zfV61ON2rWf5mJ+0xZmHggimF/Gaps+nI4adsPtXKaRLs59
	j2SCgDfV6QtyvsgnYey2TBH7w/Y0VcH8/Q/I79WMPDHOXafkP+rkclEqROsFKblKBTxU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kp9tY-0003Fg-Hf@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:36 +0000

commit ff3d2dff9b80929c91e157b12947be29b50348b6
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:16 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f2c4318c88..9f9f7ee2f0 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 8d0c50bfa4..f7b88065bb 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -337,7 +337,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53915.93508 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tj-0001A2-T4; Tue, 15 Dec 2020 12:57:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53915.93508; Tue, 15 Dec 2020 12:57:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tj-00019t-Pa; Tue, 15 Dec 2020 12:57:47 +0000
Received: by outflank-mailman (input) for mailman id 53915;
 Tue, 15 Dec 2020 12:57:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ti-00019m-MQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ti-0006Wy-Le
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ti-0003GV-Ku
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yQx+3a7MPTjpvPHAN0Kd78kKy+LUPlIizbVPMu2OmRY=; b=dhFCg9kQ/pqDI6RaQiwnWVo5Ew
	42oGJQH1LWK1uP7EwS5eaVu3MUTGRt7ffpW7oJ9aohHmWAGVEywzPUrfqJizQdh/lygOkxFw4cQsJ
	H0cteN8xTpFyWpaPZae9aqk23GY36JgA6wn8mH4xAn8h87O0LCeVKIjm6Ldlx3B8iXEA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kp9ti-0003GV-Ku@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:46 +0000

commit 34f008318d191dfee1f58be710438fda5a8fc914
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:19 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index f7b88065bb..0d355bbcb8 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:57:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:57:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53921.93512 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tt-0001C3-V4; Tue, 15 Dec 2020 12:57:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53921.93512; Tue, 15 Dec 2020 12:57:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9tt-0001Bu-RZ; Tue, 15 Dec 2020 12:57:57 +0000
Received: by outflank-mailman (input) for mailman id 53921;
 Tue, 15 Dec 2020 12:57:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ts-0001Bb-PQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ts-0006X9-Oh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ts-0003HK-Ns
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:57:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LwCPlqRvMBzdUUwSKeYFowGFu+fO40JvdXFE/NbU6jo=; b=4vjXrNr8Mi0fmNb318l2A9a2dm
	A6aqSSnzRVIr8BpQ2fXbORR4I3x9ZYJsrchDzKIv/spAeSSyaDoseQz654NAHMtFbstUT7Nr8j9X+
	sxmyCgn5DjTTxofx/xLtt0v6zBgZqmxV+c5DIo1Rpm5m2OI2cEmJVJlqoDvvN9UVFCjk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kp9ts-0003HK-Ns@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:57:56 +0000

commit 496306324d8d933a811cbd3cbfded4cc45034a32
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:36:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:01 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/include/xenstore_lib.h           |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/include/xenstore_lib.h b/tools/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/include/xenstore_lib.h
+++ b/tools/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ad1903c555..cbefe4c819 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -403,8 +404,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -420,6 +426,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -476,8 +485,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1239,8 +1249,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1879,6 +1893,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1899,6 +1914,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1921,7 +1937,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -1963,6 +1979,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index cf239c044b..7169da9851 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -67,8 +67,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -188,6 +194,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -209,21 +218,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -289,58 +311,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -383,15 +431,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -497,8 +551,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -641,8 +695,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -729,6 +785,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 9f1dc6d559..80c03acbea 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -146,7 +146,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53924.93516 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9u4-0001E1-3q; Tue, 15 Dec 2020 12:58:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53924.93516; Tue, 15 Dec 2020 12:58:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9u4-0001Dt-0k; Tue, 15 Dec 2020 12:58:08 +0000
Received: by outflank-mailman (input) for mailman id 53924;
 Tue, 15 Dec 2020 12:58:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9u2-0001Dh-ST
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9u2-0006XV-Rm
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9u2-0003IR-Ql
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yFeUlkdIkWdFYoo6AJdUftNoM8hZfHzjsW4ng9bSTcQ=; b=cwxlTN2oJ0u7jGEf1gDx/CaIiX
	ISdRxOKHWLvtACwX7dtpZG+DStzFR8WE+Y/TA22VIzEqDpAgIApnwNBo7mZ8XZt79momyIXpbasdU
	kAt494vsUj36ThD1Xl73nxgMKCLhWolZCE+ez9h4gmgENwzfdHINPRns/hMKx80GaO6k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kp9u2-0003IR-Ql@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:06 +0000

commit c46eff921209a2526f0055cdb76fbf69176b729e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:36:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:04 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 0d355bbcb8..ff9fbbbac2 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -336,6 +336,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53925.93519 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uE-0001FK-5I; Tue, 15 Dec 2020 12:58:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53925.93519; Tue, 15 Dec 2020 12:58:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uE-0001FC-2K; Tue, 15 Dec 2020 12:58:18 +0000
Received: by outflank-mailman (input) for mailman id 53925;
 Tue, 15 Dec 2020 12:58:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uD-0001F6-02
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uC-0006Xh-Va
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uC-0003J3-Ts
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zOx2T2n6lbHSrsDDsYf8KmLr832E3qxanIkJNaDIILY=; b=MTXGXIYlc+5zwLh/43KaJ/TADS
	mO5smLIjP3CD9+Zg4SOoavTQsHHNdH+s7pvUkCW9dtsWWZP9xiFaWYYdhXgESvJHiWOz/E4EzbGeV
	7IrfYzIMnyNDi3edBZIuOc+GynMDhzVKqz/BpTs+crSJiaHo58FcYYXdu6/B/csVJHJo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kp9uC-0003J3-Ts@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:16 +0000

commit bf0703992c62d89e30a9051c363055387257f24f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:36:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:39 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index ea9e1b7620..ebe18b8e31 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -31,6 +31,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index ff9fbbbac2..39d6d767e4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53929.93526 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uO-0001HR-7b; Tue, 15 Dec 2020 12:58:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53929.93526; Tue, 15 Dec 2020 12:58:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uO-0001HC-3u; Tue, 15 Dec 2020 12:58:28 +0000
Received: by outflank-mailman (input) for mailman id 53929;
 Tue, 15 Dec 2020 12:58:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uN-0001H3-3U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uN-0006Xs-2p
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uN-0003Js-1e
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XJRW5hM1YIC5aHR/dh/LIwmUvzFgVBTTkGTsBxobo/U=; b=p/epyB0PXocOGTLAlDalL7nNrF
	i5o/eMikYT6wY4UEsGvzOKUZD+dpETA4TSSWkbWLOHuiQFsEgmWb9cVbDlfnxdPUl9NguF9dPe2J1
	UDuXjkX9WLoPgZCDutBpOFnlTjTBdB9HMNjvgZ00A3Rll/cynuhVNEdl7XSgMySct6WE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kp9uN-0003Js-1e@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:27 +0000

commit 5a3f7a05a3680a52d52053fa0a3ce9afea5b8c81
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:36:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:42 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cbefe4c819..c929cbbc3b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -673,6 +673,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53936.93528 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uY-0001Jc-8g; Tue, 15 Dec 2020 12:58:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53936.93528; Tue, 15 Dec 2020 12:58:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9uY-0001JU-5T; Tue, 15 Dec 2020 12:58:38 +0000
Received: by outflank-mailman (input) for mailman id 53936;
 Tue, 15 Dec 2020 12:58:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uX-0001JJ-6b
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uX-0006YN-5x
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uX-0003KT-51
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hYfUMdSaz6QjdSb6QChMVsVqiNtbcf/KHCGPrBM61DI=; b=NaATsJetTE7ExBsd+IUs8l7pPZ
	wHSoF8CnM6YiWwp6fh0OD7PVmM+xkKmzTyf+whbc+vrEmEhPWtEgP3ExQPf+EueAXJw6hFECrfyoy
	M4D/FdeVrkVFW99UbON5u4UIpYBw1zMAV1TO+rXjv0WMRRm42TaOKwi1Pw6jxXLTrbKg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kp9uX-0003KT-51@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:37 +0000

commit d2fa370d3ef9cbe22d7256c608671cdcdf6e0083
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 13:36:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:45 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c929cbbc3b..746a1247b3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1337,6 +1337,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1395,8 +1421,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1453,14 +1481,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1475,6 +1503,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->pollfd_idx = -1;
 	new->write = write;
 	new->read = read;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2136,8 +2165,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2149,8 +2179,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 6c21d5bb9a..4c6c3d6f20 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -77,6 +77,9 @@ struct connection
 	/* Who am I? 0 for socket connections. */
 	unsigned int id;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7169da9851..7d348d57f3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -286,6 +286,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -303,6 +307,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53949.93533 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9ui-0001MN-Ax; Tue, 15 Dec 2020 12:58:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53949.93533; Tue, 15 Dec 2020 12:58:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9ui-0001MF-71; Tue, 15 Dec 2020 12:58:48 +0000
Received: by outflank-mailman (input) for mailman id 53949;
 Tue, 15 Dec 2020 12:58:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uh-0001Ls-9J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uh-0006YV-8e
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9uh-0003L9-7w
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YiZd9DyIDhZLI2QusENODkE8zE+EhgJ4gK1TpX5cppA=; b=Y96owk0ZskYURu98ycP+QaoFlD
	F2QSxRkZcOYx516X05bzpsgRT46+UGtWWlzKHhczS1vSwStFlhN2guggCbvDNRinEU0HGi6196v5i
	SbKSTEyrFXDEW+JTYYzOqkuQRHV67pYOkkpUoqUCF63JZ/wGhPfs2lgPocnNrEh+LlHQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kp9uh-0003L9-7w@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:47 +0000

commit 491a077ed4c51f26ee77bc92ca346942482cf24e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:37:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:37:14 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 9f9f7ee2f0..6ee3552ec2 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:58:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:58:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53959.93540 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9us-0001Ph-FX; Tue, 15 Dec 2020 12:58:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53959.93540; Tue, 15 Dec 2020 12:58:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9us-0001PW-C7; Tue, 15 Dec 2020 12:58:58 +0000
Received: by outflank-mailman (input) for mailman id 53959;
 Tue, 15 Dec 2020 12:58:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ur-0001PJ-C8
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ur-0006Yf-BS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9ur-0003MJ-Aj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:58:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2EoKaa3dte1pxLMtUItETGQEbSFMdvhqRxh1Fd3ZDjQ=; b=W26VYvIXxz6KfN5eoR1gE4Ko4M
	JJniepJEdHuqIkFfQaJqtYr7imqmZG4y22cwK65Lz2NeaISP/xwnDFc4/7KrxGpeeNXFM2euHYIkD
	KLJIzciP7aD+8KOCNGvW0gXYODGG974hPuHOzuEDo+2F96Kre9FG10Itkc8k4Sfwird4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kp9ur-0003MJ-Aj@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:58:57 +0000

commit 2a3f8d12f00ea87c8ac84b8a2f84d1afe42230f3
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:37:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:37:33 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53966.93544 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9v3-0001S4-Gt; Tue, 15 Dec 2020 12:59:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53966.93544; Tue, 15 Dec 2020 12:59:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9v3-0001Rw-Dd; Tue, 15 Dec 2020 12:59:09 +0000
Received: by outflank-mailman (input) for mailman id 53966;
 Tue, 15 Dec 2020 12:59:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9v1-0001RX-G0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9v1-0006Yz-FM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9v1-0003N8-EU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gtAKZHcd7kJguw/Xo15rbWqB0zbIEzSbd1wNfaTyCzc=; b=Nj7HCwmTUjejy2Co/CSt5yMVYl
	oNR88nLQpF4bHNuujga1HGXa6qvcdyOtPyo6IdiCNFmqjFhI474ZLxZ4cmp9Cunk1PlTXBd5e+xgC
	I/vqeBIoc2ZyeGDbwqmCRSfKPtNCNafvSIdE6migtLWEHrxaeDICi94h935NOoU+ZMn8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kp9v1-0003N8-EU@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:07 +0000

commit e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:40:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:40:27 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 1b894d0124..6d3561ea77 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index cfea5b5523..e41330ca55 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1036,7 +1036,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ca94c2bedc..a71b935c10 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1909,7 +1909,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 663e76c773..27dc0f8ed7 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -113,7 +113,7 @@ static int parse_pcid(const char *s)
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 30d6f375a3..1a2e5e41ab 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -676,7 +676,7 @@ static void __init noreturn reinit_bsp_stack(void)
         asm volatile ("setssbsy" ::: "memory");
     }
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 861a227dbd..81ceafce98 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1635,6 +1635,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 51a4cdbf7c..b47addb3c8 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,13 +155,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
             "jmp %c[fun];"                                              \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
@@ -176,12 +176,6 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53971.93548 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vD-0001UL-IL; Tue, 15 Dec 2020 12:59:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53971.93548; Tue, 15 Dec 2020 12:59:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vD-0001UD-FI; Tue, 15 Dec 2020 12:59:19 +0000
Received: by outflank-mailman (input) for mailman id 53971;
 Tue, 15 Dec 2020 12:59:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vB-0001Tl-Jt
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vB-0006Z6-JF
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:17 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vB-0003Ni-HX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:17 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=NdVHWm+5s+lj5aqPWVkgM7BkRMQ7vUQjP0s0IhZ5/Tc=; b=OhsMu9wIz8/7ygk4mm9kB6w/yW
	bipsnmPgkp8TJiG4CdPDLGCarDM2IfzALlcB0ZQA2PM01EOo1/bdzLi/8dhJxrk/cIfOUoyeYfEhN
	t6WreaPheZip6+ZvaYwjmraizq5Wk0fLwnzUmx0Me2Ub6ev+yDb6ryPz/XQnU2+nLXdA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kp9vB-0003Ni-HX@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:17 +0000

commit 058e469ab4d5cc5959423aafd6ba181dfc310a7f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:41:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:41:09 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 6d3561ea77..3f8d8be280 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:29 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:29 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53980.93552 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vN-0001Xh-Jv; Tue, 15 Dec 2020 12:59:29 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53980.93552; Tue, 15 Dec 2020 12:59:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vN-0001XW-Gq; Tue, 15 Dec 2020 12:59:29 +0000
Received: by outflank-mailman (input) for mailman id 53980;
 Tue, 15 Dec 2020 12:59:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vL-0001WY-NS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vL-0006Zb-Me
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vL-0003OM-Lp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2F6c/cJF/s1GmluI5vM+tPtvbhnKEGES30sLqNLZvH8=; b=10bkb88cD80TWDqwq8gPqGJyZP
	NZFTAlnEk28Zcy8qsFGgpMkIQuMb4TJeXUzJD1JshXhIrcaZNimLyjwnhEfb/wO8ejaZsJMk/5QI7
	l9hQB9kntQ0TLPhr0ToyFTORNNUpfnvu/+FUjpAsmqVAIgalbNipuZIMW3uIblDaXxxw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kp9vL-0003OM-Lp@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:27 +0000

commit e6ebd394385db52855d1517cea829ffff68b34b8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:41:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:41:23 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 3f8d8be280..4932ed62f1 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -710,7 +705,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -2047,20 +2042,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index e41330ca55..d90627d4f7 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -991,8 +991,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a71b935c10..1466064d0c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,8 +1850,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 27dc0f8ed7..1a607f856e 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,7 +110,7 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b47addb3c8..4d8822f78c 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,18 +155,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-            "jmp %c[fun];"                                              \
+            instr "[fun]"                                               \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
             : [stk] "r" (guest_cpu_user_regs()),                        \
-              [fun] "i" (fn),                                           \
+              [fun] constr (fn),                                        \
               [skstk_base] "i"                                          \
               ((PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8),               \
               [stack_mask] "i" (STACK_SIZE - 1),                        \
@@ -176,6 +176,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index df657dc69f..3900d7b48b 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -337,7 +337,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 111ccd7e61..09ea0fa2cd 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 struct hvm_emulate_ctxt;
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:39 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:39 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53990.93555 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vX-0001a7-Ld; Tue, 15 Dec 2020 12:59:39 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53990.93555; Tue, 15 Dec 2020 12:59:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vX-0001Zz-IQ; Tue, 15 Dec 2020 12:59:39 +0000
Received: by outflank-mailman (input) for mailman id 53990;
 Tue, 15 Dec 2020 12:59:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vV-0001ZW-QB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vV-0006Zl-PX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vV-0003PM-Oi
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=p5fRWy6cZxC/g0aDlf3MT3jgKXIGXGVs/qX+KhnkioQ=; b=T23RiLQofI8ttnJbTCPWE49anR
	Vv56Lu57Y2FgINtYUafbDEj5BaL7tWHZVxj439Mw5vreCwtfFrVuZ/DD6VZ7CSB1ckdvdwJZ4Ehvu
	jYsmmoqsJTB0owozGZTRDKMih7hgWOjfROAmGgsJI1HTQK7JcP/gk5IGDLPfV/FIbB0s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/irq: fix infinite loop in irq_move_cleanup_interrupt
Message-Id: <E1kp9vV-0003PM-Oi@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:37 +0000

commit ca85682e8c16361fdf3814c9b25a2ec3ff4f8bed
Author:     Roger Pau Monné <roger.pau@citrix.com>
AuthorDate: Tue Dec 15 13:42:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:42:16 2020 +0100

    x86/irq: fix infinite loop in irq_move_cleanup_interrupt
    
    If Xen enters irq_move_cleanup_interrupt with a dynamic vector below
    IRQ_MOVE_CLEANUP_VECTOR pending in IRR (0x20 or 0x21) that's also
    designated for a cleanup it will enter a loop where
    irq_move_cleanup_interrupt continuously sends a cleanup IPI (vector
    0x22) to itself while waiting for the vector with lower priority to be
    injected - which will never happen because IRQ_MOVE_CLEANUP_VECTOR
    takes precedence and it's always injected first.
    
    Fix this by making sure vectors below IRQ_MOVE_CLEANUP_VECTOR are
    marked as used and thus not available for APs. Also add some logic to
    assert and prevent irq_move_cleanup_interrupt from entering such an
    infinite loop, albeit that should never happen given the current code.
    
    This is XSA-356 / CVE-2020-29567.
    
    Fixes: 3fba06ba9f8 ('x86/IRQ: re-use legacy vector ranges on APs')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/irq.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index f82c93dfdc..768a8fc7c9 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -448,8 +448,15 @@ int __init init_irq_data(void)
     set_bit(HYPERCALL_VECTOR, used_vectors);
 #endif
     
-    /* IRQ_MOVE_CLEANUP_VECTOR used for clean up vectors */
-    set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
+    /*
+     * Mark vectors up to the cleanup one as used, to prevent an infinite loop
+     * invoking irq_move_cleanup_interrupt.
+     */
+    BUILD_BUG_ON(IRQ_MOVE_CLEANUP_VECTOR < FIRST_DYNAMIC_VECTOR);
+    for ( vector = FIRST_DYNAMIC_VECTOR;
+          vector <= IRQ_MOVE_CLEANUP_VECTOR;
+          vector++ )
+        __set_bit(vector, used_vectors);
 
     return 0;
 }
@@ -734,10 +741,6 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
 {
     unsigned vector, me;
 
-    /* This interrupt should not nest inside others. */
-    BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
-                 APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
-
     ack_APIC_irq();
 
     me = smp_processor_id();
@@ -781,6 +784,11 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
          */
         if ( irr & (1u << (vector % 32)) )
         {
+            if ( vector < IRQ_MOVE_CLEANUP_VECTOR )
+            {
+                ASSERT_UNREACHABLE();
+                goto unlock;
+            }
             send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
             TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY,
                      irq, vector, smp_processor_id());
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:49 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.53997.93559 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vh-0001dS-Ok; Tue, 15 Dec 2020 12:59:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 53997.93559; Tue, 15 Dec 2020 12:59:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vh-0001dL-Lu; Tue, 15 Dec 2020 12:59:49 +0000
Received: by outflank-mailman (input) for mailman id 53997;
 Tue, 15 Dec 2020 12:59:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vf-0001cS-TA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vf-0006Zy-SH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vf-0003Pw-RZ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=f4se69N3JPrPQ9TXQumioQ5kgsPA1jw6yGzcZ+nG3qI=; b=pcvjRP2njZcnLLUBLoJ0MHM3vp
	LjIDHYnL2T3mUAUCW3K1uFhBXV2LMXs1/o7CtGDGLCgx1YPtS65GqqHpyvT7UmUZ9VuPD4qqZ2o2W
	CRBt8FAYMrCmMLaNQbSb+0fCQkLo4H6Ok18qsZY7fZoUiWI45j/ousxwBFxoGEgAZY9Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kp9vf-0003Pw-RZ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:47 +0000

commit dc8b01affd7f6f36d34c3854f51df0847df3ec0e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:42:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:42:51 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index d508d57219..3310dc00d7 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -55,6 +55,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -605,6 +612,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 12:59:59 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 12:59:59 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54006.93564 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vr-0001fW-QY; Tue, 15 Dec 2020 12:59:59 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54006.93564; Tue, 15 Dec 2020 12:59:59 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9vr-0001fN-NO; Tue, 15 Dec 2020 12:59:59 +0000
Received: by outflank-mailman (input) for mailman id 54006;
 Tue, 15 Dec 2020 12:59:58 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vp-0001f8-Vp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vp-0006a8-VD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9vp-0003RP-UQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 12:59:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xMHIeuWwcFUE4txvaPlGUuE94NcUKCBKvT5Oq3DVaiM=; b=dXyM3lbzKCqQ5sGonmz0uBtpTk
	cxRP/yPLDBaF0nw1ueLW8TeQPy4HgzZIXvw2RBtTI2YKDdFN1Xns9LidaZDSP7fUiRk+1J/bJQcn6
	qKxxSaqQk0C8IVBYH+NApWc/M126gcZKRBpWXd5FzecRnL0S+8k26wheBEJRDLsZRHMk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kp9vp-0003RP-UQ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 12:59:57 +0000

commit c5e63651fdc706954d920a2d98f74f4a21b46a7e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:46:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:46:37 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 3310dc00d7..2fb01b82db 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -252,6 +252,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
+         /*
+          * This also acts as the read counterpart of the smp_wmb() in
+          * map_control_block().
+          */
          !guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
         /*
@@ -478,6 +482,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -488,10 +493,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:00:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:00:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54013.93567 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9w0-0002QC-S7; Tue, 15 Dec 2020 13:00:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54013.93567; Tue, 15 Dec 2020 13:00:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kp9w0-0002Q3-Oq; Tue, 15 Dec 2020 13:00:08 +0000
Received: by outflank-mailman (input) for mailman id 54013;
 Tue, 15 Dec 2020 13:00:08 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9w0-0002OU-2v
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:00:08 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9w0-0006cZ-2E
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:00:08 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kp9w0-0003UN-1J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:00:08 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FXJ3ODV6E5ofqtA4Yec6fCV+u6cEGRa28+Yir6NGJu4=; b=zVeDLaEg/bUf1ucKLDlM/urya9
	TIAR3wDgYMQ+zbZ141rL/xWcYmpK5Zast4PW6LxEsUJf/EYk9tbGeErkX0IwHusEQyYOivBeVTVbD
	4X2XYK3Wmd80j2kIJGjIE1m1CbQvXmtHDlFi5mXhqECdj8+VyHsL9nbUz0OEiTxPcknk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/PV: guest_get_eff_kern_l1e() may still need to switch page tables
Message-Id: <E1kp9w0-0003UN-1J@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:00:08 +0000

commit 904148ecb4a59d4c8375d8e8d38117b8605e10ac
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:47:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:47:45 2020 +0100

    x86/PV: guest_get_eff_kern_l1e() may still need to switch page tables
    
    While indeed unnecessary for pv_ro_page_fault(), pv_map_ldt_shadow_page()
    may run when guest user mode is active, and hence may need to switch to
    the kernel page tables in order to retrieve an LDT page mapping.
    
    Fixes: 9ff970564764 ("x86/mm: drop guest_get_eff_l1e()")
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
---
 xen/arch/x86/pv/mm.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/pv/mm.h b/xen/arch/x86/pv/mm.h
index 2a21859dd4..62b1194e87 100644
--- a/xen/arch/x86/pv/mm.h
+++ b/xen/arch/x86/pv/mm.h
@@ -11,10 +11,15 @@ int new_guest_cr3(mfn_t mfn);
  */
 static inline l1_pgentry_t guest_get_eff_kern_l1e(unsigned long linear)
 {
+    struct vcpu *curr = current;
+    bool user_mode = !(curr->arch.flags & TF_kernel_mode);
     l1_pgentry_t l1e;
 
-    ASSERT(!paging_mode_translate(current->domain));
-    ASSERT(!paging_mode_external(current->domain));
+    ASSERT(!paging_mode_translate(curr->domain));
+    ASSERT(!paging_mode_external(curr->domain));
+
+    if ( user_mode )
+        toggle_guest_pt(curr);
 
     if ( unlikely(!__addr_ok(linear)) ||
          __copy_from_user(&l1e,
@@ -22,6 +27,9 @@ static inline l1_pgentry_t guest_get_eff_kern_l1e(unsigned long linear)
                           sizeof(l1_pgentry_t)) )
         l1e = l1e_empty();
 
+    if ( user_mode )
+        toggle_guest_pt(curr);
+
     return l1e;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54078.93614 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHH-00052S-DX; Tue, 15 Dec 2020 13:22:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54078.93614; Tue, 15 Dec 2020 13:22:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHH-00052L-Aa; Tue, 15 Dec 2020 13:22:07 +0000
Received: by outflank-mailman (input) for mailman id 54078;
 Tue, 15 Dec 2020 13:22:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHF-00052C-Df
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHF-00071X-Cu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHF-0005Zu-C0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=UyHa/hyH3Fu5ppcMFcjG8XsRw0nF0y8w9I15/nHU0rs=; b=1WglrU5jUdQxcqpWK1UdQn+GKi
	ylOhvepXEOJHF93Vy9yewf3Gv1LB//qZ+7NBcQjqoJv2AVOs+p6or+3NoaVTBe2TodQfip4DTWJsL
	pCIb31K6UFr7UDVWZ7V0zZWQgzzYPlUM35c98+qQKwPc8YyAm2cGiXbJTnDRHLChkbOA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpAHF-0005Zu-C0@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:05 +0000

commit f130d5f013b205d1b15fa8395e473e422cb51945
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:05:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:16 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54080.93619 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHR-00054E-FD; Tue, 15 Dec 2020 13:22:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54080.93619; Tue, 15 Dec 2020 13:22:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHR-000546-CI; Tue, 15 Dec 2020 13:22:17 +0000
Received: by outflank-mailman (input) for mailman id 54080;
 Tue, 15 Dec 2020 13:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHP-00053n-J0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHP-00071f-Hn
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHP-0005aU-F4
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0ccgvwLAXW1hbgKNJj1TpdnKBDO7/A+6Hsxpt9EIChk=; b=lrw5bFBLShKf6YW8AaYr8sdeE+
	l/+LqbgWBcQVGVoiP2PD581UJFkquTpxEsvtNDwjiXXw0dBpk4oCjjhSLF2svFQP4TczFwT1jc+Fo
	PqOHRE+CMvBtPK7RR1ZUmTNVz/hwIfhi5OkxAwMoaCGSffcPzR3n7tPfWzP2YuIvSBA0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpAHP-0005aU-F4@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:15 +0000

commit 9c898a82b84247fb02deb8ae2adb1f749631a7b1
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:38 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 7bd959f28b..62a17a686e 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -419,7 +419,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -429,7 +430,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -457,14 +458,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -1001,7 +1003,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1041,7 +1043,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1117,7 +1119,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1256,7 +1258,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1516,7 +1518,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index c4c32bc88f..29d638fbc5 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54081.93623 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHb-00056F-Gb; Tue, 15 Dec 2020 13:22:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54081.93623; Tue, 15 Dec 2020 13:22:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHb-000568-Do; Tue, 15 Dec 2020 13:22:27 +0000
Received: by outflank-mailman (input) for mailman id 54081;
 Tue, 15 Dec 2020 13:22:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHZ-00055t-MR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHZ-00071p-Lg
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHZ-0005b8-Jx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6S+Y6XK/XFDRRyvuryYCRgvYBavMNzjDrIbSzGEMa8g=; b=ajbE/0BIvGZ7TGqjYeovIVyUxR
	nVb5p6CE2lFhqllRJzgtLWSPUiX4rQUFRp+53LQIXgKxUdIVNbmrQGBmmrqxXhWInzMRaHCAe7uDB
	JKfT1pD0ZdB/Cfc/wyqj3hIHXYTVyeSGf0Bd2p82xiNwzR7lfL/PKlX0D93DF6XpGfFA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpAHZ-0005b8-Jx@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:25 +0000

commit da67712173474c31695a56a269a8b069f7eb36a6
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:43 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 62a17a686e..2f989524b4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1270,13 +1270,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1298,7 +1302,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1313,7 +1317,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1322,12 +1333,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54083.93627 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHl-00058I-Jz; Tue, 15 Dec 2020 13:22:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54083.93627; Tue, 15 Dec 2020 13:22:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHl-00058A-Gh; Tue, 15 Dec 2020 13:22:37 +0000
Received: by outflank-mailman (input) for mailman id 54083;
 Tue, 15 Dec 2020 13:22:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHj-00057u-PW
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHj-00072D-Ok
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHj-0005bk-Nv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+mR9TTuMDUfQELgV12juVkUVmm0Eh4D/MDMwNiaHliE=; b=o+EsDk6ZlNhcOQkLyM4PERJAL3
	dldKHHVOBe3vSlLkgKwb6vcODh4u5CkVfT8Yrsn9sfQdFTgliptg9ea4XugaN5MfQI2s5pEG8SwB2
	f2kpLm45LRuRPUDl3IbUnAeRw+bwaBkTapr4DYGFCKrah4MWrrdBby+70vgw0wLdAZ7g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpAHj-0005bk-Nv@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:35 +0000

commit 3beffb3ed0e999e38a6ff4dec042b38c23d77e48
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:47 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2f989524b4..c971519e54 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -927,11 +927,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -964,7 +959,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -984,6 +978,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -1000,18 +997,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54086.93631 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHv-0005A8-L1; Tue, 15 Dec 2020 13:22:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54086.93631; Tue, 15 Dec 2020 13:22:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAHv-0005A0-IF; Tue, 15 Dec 2020 13:22:47 +0000
Received: by outflank-mailman (input) for mailman id 54086;
 Tue, 15 Dec 2020 13:22:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHt-00059g-SY
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHt-00072L-Ro
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAHt-0005cR-Qq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QlKLLBCgy4or287vFEt0aFBuNYASu8gn3avlNU5Z/yM=; b=gtyCI5DxUEe9yLY8NgBK94xATP
	EomeMBww/+BOmvuUftASy3feTyo6dstkbnskvRXfQNv27g6ml4stqb1ksx7ouyBQ6Vkq3BpLc9Rx5
	R1VvgLMMll/XCAxaVIEMD0fEhyGCg0nhK1J4rrwcKUzKd54ah2PVlKGiDfVFzs2gY4ns=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpAHt-0005cR-Qq@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:45 +0000

commit 4e298fa40781231ddc3f17e3e14e869c1c591722
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:53 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:22:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:22:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54087.93635 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAI5-0005C7-Mv; Tue, 15 Dec 2020 13:22:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54087.93635; Tue, 15 Dec 2020 13:22:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAI5-0005Bz-Jl; Tue, 15 Dec 2020 13:22:57 +0000
Received: by outflank-mailman (input) for mailman id 54087;
 Tue, 15 Dec 2020 13:22:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAI3-0005Bf-Vr
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAI3-00072V-Uy
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAI3-0005dS-U1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:22:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=EpKT0cyvwaQLrUQFeJ/G3VrQap/2RlV9OxwWXNvXdac=; b=0t3YCU0om0Fkr4EGsiqLe+Yoi5
	7qcDimuM8hJMBcujWWHfAYZzYChZJB259Arsq2OA/udTwEthkA4i5edXRxh1/dX5fYDePm/5SXeo7
	mgSJkePHZG9KGYWJK3HPfKk2NMMrYNo2Lxuo8D7w+mWHAoZUxweULWLSk35xQcxTR6zQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAI3-0005dS-U1@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:22:55 +0000

commit 91992c72ed55185de07f44aacee499954143c9f3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:58 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c971519e54..f38196ae28 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1285,8 +1285,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1296,8 +1298,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1306,9 +1310,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1336,6 +1342,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 06359503f0..2d0d87ee89 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -372,7 +372,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -438,7 +438,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -473,9 +473,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54088.93639 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIF-0005E5-Ob; Tue, 15 Dec 2020 13:23:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54088.93639; Tue, 15 Dec 2020 13:23:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIF-0005Dx-LT; Tue, 15 Dec 2020 13:23:07 +0000
Received: by outflank-mailman (input) for mailman id 54088;
 Tue, 15 Dec 2020 13:23:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIE-0005Dl-28
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIE-00072y-1U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIE-0005eE-0k
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QqxlHD5QbdsPUBjVSDQlaSz8VDqjuqq6hvEpCJdVdrw=; b=fZSFIoFF8keUAq8AluOTIqYJ3E
	oImeewnnWWyyue3y0gAMHoLe+XP/ai0hVv81cV04gP1OMVe51DqUhHa8rZnwUEAVl74x4L4T885RW
	1YTUXAMLPYKbRSWEdgJVhgwSCeiBelZ4Tm9Zf8Bg9Xis1GAfUpxH0O1OKmEuXrH7davY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: rework node removal
Message-Id: <E1kpAIE-0005eE-0k@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:06 +0000

commit 117521e9c099d92f60753ff2bb30d97eef6e8137
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:03 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f38196ae28..dfdb64f3ee 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1089,74 +1089,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1167,11 +1169,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1209,7 +1213,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54090.93643 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIO-0005Fn-QY; Tue, 15 Dec 2020 13:23:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54090.93643; Tue, 15 Dec 2020 13:23:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIO-0005Ff-N6; Tue, 15 Dec 2020 13:23:16 +0000
Received: by outflank-mailman (input) for mailman id 54090;
 Tue, 15 Dec 2020 13:23:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIO-0005FY-5N
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIO-000736-4g
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIO-0005ev-3d
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Xuw6bZpt9pUYHZBopbjGZs9Fo+u5UAJ42kUhzG1mU28=; b=W0j1Tr1xMnsDHv5RB7bNwCkQGp
	fQyCFwUsCfme0d2WMI40/ga5ltxdl9XZ+kCoEeO19Z3JV2m1R9I1wtkrulB+EJn2Xxuagwc79MmFX
	kfwlHI/kKK9Stm0y9r5zl8OSpMSJZnJ1z1zhY3aczN6x7umnUM+ko5n1htLqniqvcZ3g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpAIO-0005ev-3d@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:16 +0000

commit 3d0e1a15b31b690018e57547c6b82f442b1cbc76
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:07 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index dfdb64f3ee..20a7a35815 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1120,8 +1120,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1133,7 +1133,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1145,6 +1145,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1174,8 +1175,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54093.93648 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIY-0005Hy-UF; Tue, 15 Dec 2020 13:23:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54093.93648; Tue, 15 Dec 2020 13:23:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIY-0005Hm-QV; Tue, 15 Dec 2020 13:23:26 +0000
Received: by outflank-mailman (input) for mailman id 54093;
 Tue, 15 Dec 2020 13:23:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIY-0005He-8W
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIY-00073G-7r
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIY-0005g5-6u
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DDm65ZWr493bQ4Pkdd4fEG0zbRQ0wwYd0ocRLLwd8Y0=; b=BBxIlXqy6j6T+G17oAFpbNsctR
	CxEMLtrVBkAs4zvHqkDbNOGkjNT2RZi9HOJDD6r2x2detaJHAv4GRjyOaywyXyX+b/Zoe7T8YqxC8
	IXP6kZvHHwbkj3JHrDuFHkxbumpiar+zMSgZJR+05JzHujed5CNJ2P4DSpyaGfh9R8uo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpAIY-0005g5-6u@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:26 +0000

commit 52593586d58086fe27cfbed3dc9beeae3d9c8c09
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:12 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 20a7a35815..79d305fbbe 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -403,14 +403,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -427,7 +427,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -439,12 +439,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -470,8 +471,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -480,16 +480,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -536,7 +536,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -582,8 +582,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -759,16 +758,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -947,13 +945,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1230,7 +1228,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1241,13 +1239,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1258,21 +1255,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1547,8 +1544,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 29d638fbc5..47ba0916db 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 2d0d87ee89..aa9942fcc2 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -650,12 +650,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -676,12 +676,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54096.93650 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIi-0005Ja-Uy; Tue, 15 Dec 2020 13:23:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54096.93650; Tue, 15 Dec 2020 13:23:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIi-0005JS-S4; Tue, 15 Dec 2020 13:23:36 +0000
Received: by outflank-mailman (input) for mailman id 54096;
 Tue, 15 Dec 2020 13:23:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIi-0005JK-Bq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIi-00073i-B3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIi-0005go-AF
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Vgnsya5wdSVhIRhVooMFFQM7aa+i8O9to0pQwiUQPLw=; b=x3XM2UJst8IG36af93N20fKV2X
	KumGB1ozBV9vSS8nPrCpz6+SoHDhyfTRSFmE8FY22T6cHm/S1SFaTMLTEV4a9wT8h9tLaWJo/4xwG
	mHNcbf0yUNpbnAyhf8KM+tDRJmUe10jU4d+rY2ubufCwgc68OiJz1xHp+56z2adWpC/4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpAIi-0005go-AF@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:36 +0000

commit 5073c6b169dd12ec02afc145d4177f97831646e0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:17 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index cb8009cb68..2081f20f55 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See https://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 79d305fbbe..15ffbeb30f 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -470,8 +470,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1247,22 +1247,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 47ba0916db..53f1050859 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index aa9942fcc2..a0d1a11c83 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -582,6 +585,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -603,6 +659,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54097.93654 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIt-0005L7-0d; Tue, 15 Dec 2020 13:23:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54097.93654; Tue, 15 Dec 2020 13:23:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAIs-0005L0-Tn; Tue, 15 Dec 2020 13:23:46 +0000
Received: by outflank-mailman (input) for mailman id 54097;
 Tue, 15 Dec 2020 13:23:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIs-0005Ks-Ev
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIs-00073w-E8
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAIs-0005hd-DQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=azrgwRPS0jn1JmSY8eN+x+pw3xEg5/z/3aauidvt9S8=; b=29i5ck+QGHZPLk6jqN9n/3KhyA
	6OrYMt7NnxE/AziqxaDqfwUpDoDKPaYBM6Cb4833fa3U+AQDREWSUHTUgvf8Y2mO38InLp4F+QoCX
	T1xV6cSFw7N9S9/5t/Q4qYbpbMIPWgz97VX0WT9+VnaEccTkxmMuaK/06lDT6j0VBNl4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpAIs-0005hd-DQ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:46 +0000

commit 0a79a1b1d8fc6214f162b2d7b00f5d3533109820
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:21 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 15ffbeb30f..92bfd54cff 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -360,8 +360,8 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *p_ro_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -496,7 +496,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -568,10 +568,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1058,7 +1058,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1080,7 +1080,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1143,7 +1143,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1167,13 +1167,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1239,7 +1240,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1275,6 +1276,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1282,7 +1284,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53f1050859..eb19b71f5f 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index a0d1a11c83..9fad470f83 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -202,7 +202,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -240,7 +240,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -404,7 +404,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:23:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:23:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54098.93659 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJ3-0005MU-41; Tue, 15 Dec 2020 13:23:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54098.93659; Tue, 15 Dec 2020 13:23:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJ3-0005MM-13; Tue, 15 Dec 2020 13:23:57 +0000
Received: by outflank-mailman (input) for mailman id 54098;
 Tue, 15 Dec 2020 13:23:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJ2-0005MF-Hd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJ2-000742-Gv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJ2-0005iN-G5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:23:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/DKh3PQiD45vp0eDa7FCKrR1LTr1TYMVCoFF/VN4Mv0=; b=TLX+vx8O1PhfYhnvvDbYsOE3wT
	4ArtB9HlfmcIKMJ3aWox7jdATcAcpbcnPjlCmH6E4/GixkUaoPoxRLg2yeTQxr6xHZQE8f3SY8Ct2
	0M/RcMbAvqOYU5y9qiQ/acaHrHzWmfQcO2jWxUBgDfHucBy7svE8C8ckN4fuzq3NHnbE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpAJ2-0005iN-G5@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:23:56 +0000

commit 228e5621ebdd3abd520fcdc712347f877880ee71
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:38 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54099.93663 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJE-0005Nk-5b; Tue, 15 Dec 2020 13:24:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54099.93663; Tue, 15 Dec 2020 13:24:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJE-0005Nc-2b; Tue, 15 Dec 2020 13:24:08 +0000
Received: by outflank-mailman (input) for mailman id 54099;
 Tue, 15 Dec 2020 13:24:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJC-0005NU-Kw
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJC-00074P-KF
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJC-0005jV-Iy
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AWzj9kPqs+yJ43BMdb8cgG/6xetmycJO9hSsVlGZ+KA=; b=sJZ4lW3f/BJQ4VOGEnBE+piLyM
	09lZr+kew5HzqxUud4lhcXkXTZhtNfDqt7Upz79y4/tflGbHw5QRa2sh1v/JZVjuKJigTqUaySyZB
	g307mkfNRMNpVg3d3sxBIngdyrMImF8yFDOAXLSyLE+8QRtk9lZr28Um1Ug7y8sEGUVE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAJC-0005jV-Iy@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:06 +0000

commit f4405b67aa7f33d07dd374226b0b4e3bb1fefb69
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:43 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54100.93666 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJO-0005Ow-7B; Tue, 15 Dec 2020 13:24:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54100.93666; Tue, 15 Dec 2020 13:24:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJO-0005Oo-4D; Tue, 15 Dec 2020 13:24:18 +0000
Received: by outflank-mailman (input) for mailman id 54100;
 Tue, 15 Dec 2020 13:24:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJM-0005Oc-Nl
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJM-00074Z-N3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJM-0005kQ-MD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=mT/yanY2QjF6HmSgWthBl8ib3qosbg8W69rusxtqb7Q=; b=Qy2dR4XvQM+UiyKWxX8NutZ8Yi
	td1spk+0SHbAfGJGF3r1sgjrEsZ1QY0vq/f/ydGw4m60bAfqUioJ626mKk9sTQ/+TJqxwkJvyHk1V
	EeeaHv8Q8M8eeBsQ+EfXOfgA+GvmqeboIZrQPmVIKEA8Xm0PZ4dl4abjyI/XItcngplQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpAJM-0005kQ-MD@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:16 +0000

commit 6fa3e05ff5a8083a0be29ac66d4d94bb57e252f2
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:48 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54101.93671 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJY-0005QX-9F; Tue, 15 Dec 2020 13:24:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54101.93671; Tue, 15 Dec 2020 13:24:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJY-0005QP-5u; Tue, 15 Dec 2020 13:24:28 +0000
Received: by outflank-mailman (input) for mailman id 54101;
 Tue, 15 Dec 2020 13:24:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJW-0005QC-Ql
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJW-00074h-Q3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJW-0005lE-PD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Zr4BcrVBFEcL2Kt7o+8KOyOkGaPDHH107C+ztOj1bzE=; b=S2HLUk+iHtT4f4Z7u246sWypA8
	C7ixtpBNs2jXL+NFL7r1dX3n5RVYwLohEFBZVNn/rqEqBRlBE3yG1TzeiXfe5B00epcoQIF/Q/vzC
	WD7s56l7HXychxXUIy3G4nlpDKnmo5M7Xe07gEMSZU+E9qBevOvDgnWmT80zooxNWSwM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpAJW-0005lE-PD@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:26 +0000

commit 335ef5b2b49100444aaaff19032235b1283ef1ea
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:53 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:53 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54102.93675 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJi-0005Rx-AU; Tue, 15 Dec 2020 13:24:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54102.93675; Tue, 15 Dec 2020 13:24:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJi-0005Rp-7R; Tue, 15 Dec 2020 13:24:38 +0000
Received: by outflank-mailman (input) for mailman id 54102;
 Tue, 15 Dec 2020 13:24:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJg-0005Rf-Uh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJg-000758-Ty
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJg-0005mF-SA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=t/CDKz5DuPfCL1E6GDppy9atDYMlzgeMvaF6i9W4SAQ=; b=UvZ36/5GfG8FrcXyFc88beWRXu
	Wq01tlZW/nV1z9TAJNngKIM2Zznbye4+hpGXrPDU75ivMrE/OQsOScFHqZsiDnA6r25/6hDeADkez
	ektChk21gFCg2iYaRm8u5py43UZ1CZ64RGOOYXW3qeS/iSYq3Jg/Er++gLLYSQmS9mwI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpAJg-0005mF-SA@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:36 +0000

commit 9e53440c3675f143130b72b7bf6ea17240e3c053
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:58 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:58 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54103.93679 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJs-0005TG-DJ; Tue, 15 Dec 2020 13:24:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54103.93679; Tue, 15 Dec 2020 13:24:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAJs-0005T8-AF; Tue, 15 Dec 2020 13:24:48 +0000
Received: by outflank-mailman (input) for mailman id 54103;
 Tue, 15 Dec 2020 13:24:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJr-0005Sx-2M
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJr-00075M-1B
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAJq-0005nY-W3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=karfviU8xDx6D74G8qZfBJBkQqyF8byg3Q2N84+V19w=; b=lGEQcEZC6s/dlu6A4idH6aHWue
	7PIoAWgNKAdatJEVL5VymUCAPdt5GMeX5+le1TefRM8al8TViXa6Vpa5AzVbPK135g7+IO4NP93bs
	U72wzfcd6lSNFKFoehYoYbngl31XYpuBLhdSItALoAK3GvZCZUC/r1ZHT9GdSeLngg7Q=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpAJq-0005nY-W3@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:46 +0000

commit 61d386343a576de37a8192c7621a4db01124a458
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:07:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:07:03 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:24:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:24:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54104.93683 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAK2-0005UZ-Ek; Tue, 15 Dec 2020 13:24:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54104.93683; Tue, 15 Dec 2020 13:24:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAK2-0005UR-Bi; Tue, 15 Dec 2020 13:24:58 +0000
Received: by outflank-mailman (input) for mailman id 54104;
 Tue, 15 Dec 2020 13:24:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAK1-0005UH-66
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAK1-00075W-5M
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAK1-0005oT-3Q
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:24:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=TPdMhaCR3EIugBkUpzIcUC0G4tWRHl4F/HKwO6XC90A=; b=SNKAWtCeef8SqoKf6dxyTVXukB
	Hk7mfYwRiGscVYeJfKmPvHAVnyhWRFj/fJ2gQwqqCcehw8isDF1XsTgKIUZracVsSpBv7qnOZrC2u
	daiyqaBmsSVhNEdQb57rdz3nUsC1qZA8ZofvFm8IOxDO+5Gge1Fb3EVj/NghflONBxXQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpAK1-0005oT-3Q@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:24:57 +0000

commit b1c5e402c488e4d2b78de1d08b9e98feed136ee7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:07:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:07:52 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 92bfd54cff..505560a5de 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -104,6 +104,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -409,8 +410,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -426,6 +432,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -485,8 +494,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1248,8 +1258,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1904,6 +1918,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1924,6 +1939,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1946,7 +1962,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -1988,6 +2004,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 9fad470f83..dc635e9be3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -67,8 +67,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -188,6 +194,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -209,21 +218,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -289,58 +311,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -386,15 +434,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -503,8 +557,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -647,8 +701,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -729,6 +785,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54105.93687 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKC-0005Vn-GH; Tue, 15 Dec 2020 13:25:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54105.93687; Tue, 15 Dec 2020 13:25:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKC-0005Vf-DI; Tue, 15 Dec 2020 13:25:08 +0000
Received: by outflank-mailman (input) for mailman id 54105;
 Tue, 15 Dec 2020 13:25:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKB-0005VX-9N
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKB-00075r-8k
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKB-0005qm-7U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=RADtItp3aWoiqWdlBWH6GBkHwxoc6Bs69jJjhXN8RZQ=; b=YkX0Pf3AX8MslrCaqmKvcCSdcK
	jJbE3nMQKJEcc4gr2W7CUEsBGLVhxIu5fQkb2u4HZLVR6h+PqmeoXuKAY2UWeq/MhgggswAqJb21z
	NbV30DPj+hQwEwsMK4loZUocr84y4+5xxrEnzg1bRvso3h2k5aNM0Cz4zP9Z0T0oaa6M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpAKB-0005qm-7U@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:07 +0000

commit dc871dda66a1ac1e0fc1ca5e35e380a145aaa739
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:08:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:03 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..a194cbc76f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54106.93691 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKM-0005XK-JX; Tue, 15 Dec 2020 13:25:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54106.93691; Tue, 15 Dec 2020 13:25:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKM-0005XC-GV; Tue, 15 Dec 2020 13:25:18 +0000
Received: by outflank-mailman (input) for mailman id 54106;
 Tue, 15 Dec 2020 13:25:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKL-0005X4-DP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKL-00075z-Cf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:17 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKL-0005sM-An
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:17 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=19bacONyenik+uCyhMlSRr8y/BMD/c12DQoPtA0HYQ0=; b=gWfUfGa9k7tUly/IvOGma7t/72
	VaGzAintElWhQBz1+Tdk4RNnnzBRQzKCquSdr1yu9cR1BKQu260DH+ZeSZj+BQydWO2uxVT4DAQ4E
	7A583dLna3bnHStSuoN2t3675PtNCvE9pGvG7jgLT4gEx4C/7iwej4WL+Hvtlurd2p7Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpAKL-0005sM-An@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:17 +0000

commit 49ed711a956e8bd0c634e1c030d4734eadad673b
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:08:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:17 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a194cbc76f..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54107.93694 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKW-0005Yx-Kt; Tue, 15 Dec 2020 13:25:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54107.93694; Tue, 15 Dec 2020 13:25:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKW-0005Yr-Hy; Tue, 15 Dec 2020 13:25:28 +0000
Received: by outflank-mailman (input) for mailman id 54107;
 Tue, 15 Dec 2020 13:25:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKV-0005Yg-IP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKV-00076Q-Gy
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKV-0005tP-El
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gxOuAPShglwktMsSJyujDlH1QdGTplUYYnurms2AWkA=; b=4Cz4qpK0OXzL30ZgYGaFsn+Gao
	QH1Gx6aO0ivEh+pmJrEUU88d+N+Q4VeasT2JB6lK4em73yjtZvYRfzpAjW5m0cwpq9PBdI5zAAKkB
	DCBXQHFuJxxyBclCyG5Km9MIJZoK2gPzKWSDqeE0ETiYxpzsWmpomgtXQFzLdhpvP2D0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpAKV-0005tP-El@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:27 +0000

commit 7214cc7457a2862984039e96f21a5e03bfd16c50
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:08:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:21 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 505560a5de..56b5e4578b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -682,6 +682,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54108.93699 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKg-0005aP-Mm; Tue, 15 Dec 2020 13:25:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54108.93699; Tue, 15 Dec 2020 13:25:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKg-0005aG-JX; Tue, 15 Dec 2020 13:25:38 +0000
Received: by outflank-mailman (input) for mailman id 54108;
 Tue, 15 Dec 2020 13:25:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKf-0005a7-Ka
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKf-00076d-Js
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKf-0005u9-J9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=rtP0QzO0p2PxM1Cu2bm4rqDvrJKYjsvWMfyThRQzekI=; b=S/3J0pkEhEBENkwa4KqyV5Z4R0
	fPK4QMk650AolreoeVAfrjhHINoXs6DmcnRDzFZ+6KsP/WSfj9BVc5825ZyyTc6fhYooQ9cBfJqkK
	m9fde4PspCBq+RHi/pfajpvbjPzsrkeA9YKD3SSJUuNP8Zyj1pGC6bJIJoKmCOTg0Kfw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpAKf-0005u9-J9@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:37 +0000

commit 57bbcd069b8965edef34c86893563336b4552c94
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:08:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:32 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 56b5e4578b..1d05d25a48 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1346,6 +1346,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1404,8 +1430,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1462,14 +1490,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1485,6 +1513,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2171,8 +2200,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2184,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index eb19b71f5f..196a6fd2b0 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index dc635e9be3..d5e1e3e9d4 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -286,6 +286,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -303,6 +307,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54109.93703 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKq-0005bj-OA; Tue, 15 Dec 2020 13:25:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54109.93703; Tue, 15 Dec 2020 13:25:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAKq-0005bc-LD; Tue, 15 Dec 2020 13:25:48 +0000
Received: by outflank-mailman (input) for mailman id 54109;
 Tue, 15 Dec 2020 13:25:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKp-0005bS-PI
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKp-00076l-Np
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKp-0005uz-MK
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/P84Ww3+QvFHfPCs/1P5/5wEwzCXsBKCM07vlgngGjs=; b=JDEcbA4dC8wR+FbwGdZatwnUvb
	p6v4G/eJ3nuUrbULjK7gou+rlhLSAZqQWOtdA4CSWFg+zUGDGmQeVS3zDNo0I4Vbu6dnUNcHdZ207
	pPVJeZTsSuhHefXSMxnqu9HTx53VNuyKDk/DQtzBweuVC/ExQBbC3kXdTTu+i1vFh3zs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpAKp-0005uz-MK@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:47 +0000

commit de822c4a2cc5fad708255d3589e6b05757055ccd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:09:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:09:10 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:25:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:25:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54110.93707 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAL0-0005d3-Pi; Tue, 15 Dec 2020 13:25:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54110.93707; Tue, 15 Dec 2020 13:25:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAL0-0005cv-Mp; Tue, 15 Dec 2020 13:25:58 +0000
Received: by outflank-mailman (input) for mailman id 54110;
 Tue, 15 Dec 2020 13:25:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKz-0005cm-SW
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKz-00076t-Rp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAKz-0005wC-Q8
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:25:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6y5e2He8CcgnNjUYFLEznObBvzsjex9nBtLm/AlDf7Q=; b=KKrsd7ESi5w5KQtuandh4BitOn
	PlMpElWTRDxuqtX3VN2atwZxT+vY/wS31sxKEK/fp/M3R6/UNI22clxM9WNzJNiH7IhMUwTr/Fsht
	I9iMij2LlxTdEXz+4vdmopolLXe3IJ+ja1/aBu8mFGi4OyF87oLNflUj14PS3/giLmnM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpAKz-0005wC-Q8@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:25:57 +0000

commit 13268c50c0ee6fe7ea1ccc69965ec48c49f317c1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:09:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:09:16 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:26:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:26:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54111.93711 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALB-0005eY-Sf; Tue, 15 Dec 2020 13:26:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54111.93711; Tue, 15 Dec 2020 13:26:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALB-0005eQ-Ph; Tue, 15 Dec 2020 13:26:09 +0000
Received: by outflank-mailman (input) for mailman id 54111;
 Tue, 15 Dec 2020 13:26:08 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALA-0005eF-0a
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:08 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAL9-00078q-Vi
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAL9-0005xE-UN
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=g7YzteKoYsK5TLJC0bX8N4JQJiSy0LMCOeG4tKO8I08=; b=l6jBZSDod+FuAT01pFjdoX50eb
	72L73EK12lm8DX4JNGfcM8vTrrJ2XsrA4UN1ReAlU506H+BiKfw9UIgKAz3d+iHYBEvvAVk4xkgeQ
	6b/cxmwUfiejzl4Rg7ZKp/CrDwBeGQtuiXa/C9toBAyGZelQQVAZLF5ThbY6luOAy+qU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kpAL9-0005xE-UN@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:07 +0000

commit bfc99c310fb156a4f0cacfd17c216207db8044ca
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:12:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:12:47 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
    master date: 2020-12-15 13:40:27 +0100
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c830d1225c..5114774f94 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 0c0c2a964e..ccdc4e004b 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1032,7 +1032,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ca94c2bedc..a71b935c10 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1909,7 +1909,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 44e4ea2582..92ed8a0292 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -113,7 +113,7 @@ static int parse_pcid(const char *s)
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index c9b6af826d..01d58e4879 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -676,7 +676,7 @@ static void __init noreturn reinit_bsp_stack(void)
         asm volatile ("setssbsy" ::: "memory");
     }
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 861a227dbd..81ceafce98 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1635,6 +1635,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 51a4cdbf7c..b47addb3c8 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,13 +155,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
             "jmp %c[fun];"                                              \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
@@ -176,12 +176,6 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:26:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:26:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54112.93716 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALL-0005fr-Ud; Tue, 15 Dec 2020 13:26:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54112.93716; Tue, 15 Dec 2020 13:26:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALL-0005fi-RJ; Tue, 15 Dec 2020 13:26:19 +0000
Received: by outflank-mailman (input) for mailman id 54112;
 Tue, 15 Dec 2020 13:26:18 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALK-0005fW-41
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:18 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALK-00078y-3N
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:18 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALK-0005xt-1o
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:18 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jhlTwmZwRWCPe+MdPMM8qlmj9iXBs+LbMH9fLX29DD8=; b=K1LSRJVieOoHW6itWNZD2RMtdQ
	7XI3/I4u+n56/dph/uG1z6hbxKAQYtRDi9rmO/D9RojdhN2Yxk1AiSOy3sqlwREnl3oW7r9lcXHsz
	2vigFC3N9WBlbCekiK7dugZ1SfFaoXeRwvDwM7Pg4hudU/UHDKOlCdZf8m18MG2YTHt8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kpALK-0005xt-1o@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:18 +0000

commit 5174e4202e1fdc145a661e6ad1762b9e1acdb27c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:13:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:13:19 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: 058e469ab4d5cc5959423aafd6ba181dfc310a7f
    master date: 2020-12-15 13:41:09 +0100
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 5114774f94..d47a483744 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:26:30 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:26:30 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54113.93720 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALW-0005hK-0J; Tue, 15 Dec 2020 13:26:30 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54113.93720; Tue, 15 Dec 2020 13:26:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALV-0005hC-So; Tue, 15 Dec 2020 13:26:29 +0000
Received: by outflank-mailman (input) for mailman id 54113;
 Tue, 15 Dec 2020 13:26:28 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALU-0005h1-7o
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:28 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALU-00079N-73
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:28 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALU-0005zL-6A
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:28 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=TpWMiQUe67xRbEgQn4Kdiq/AxQ6RI7lEBvF5hoj8nzY=; b=3zrMIpESsgbIFValvinhW6oDXJ
	f9FIFWFawhjOojO20OOUK1EO8fjOv8e2kIPBRgcm1lVJYQPc3lp9I/z09AjzwMSxqmR23Mfo04gJe
	TeYAyGJnzv4MqhnZlO4oFCWmWUcpSUyA/cl6n5bunuRkjSAT0xtTnUUD8vIne05epr38=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpALU-0005zL-6A@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:28 +0000

commit d8f08a44bc8da1401a9731667daecdb9b213c073
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:13:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:13:56 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d47a483744..3da81ebf1d 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -535,7 +530,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1851,20 +1846,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index ccdc4e004b..90cdab3734 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -987,8 +987,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a71b935c10..1466064d0c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,8 +1850,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 92ed8a0292..fe3d22dce6 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,7 +110,7 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b47addb3c8..4d8822f78c 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,18 +155,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-            "jmp %c[fun];"                                              \
+            instr "[fun]"                                               \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
             : [stk] "r" (guest_cpu_user_regs()),                        \
-              [fun] "i" (fn),                                           \
+              [fun] constr (fn),                                        \
               [skstk_base] "i"                                          \
               ((PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8),               \
               [stack_mask] "i" (STACK_SIZE - 1),                        \
@@ -176,6 +176,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 40385f5eaa..0db551bff3 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -326,7 +326,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 111ccd7e61..09ea0fa2cd 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 struct hvm_emulate_ctxt;
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:26:40 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:26:40 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54114.93722 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALg-0005ia-0u; Tue, 15 Dec 2020 13:26:40 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54114.93722; Tue, 15 Dec 2020 13:26:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALf-0005iS-UM; Tue, 15 Dec 2020 13:26:39 +0000
Received: by outflank-mailman (input) for mailman id 54114;
 Tue, 15 Dec 2020 13:26:38 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALe-0005iG-Bb
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:38 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALe-00079V-Aw
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:38 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALe-000607-9E
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:38 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=pK6FQWyBJnFEipsOvqdGmB4ET9qmrneYMxX2SZMcpN8=; b=I8qVMSAKq3hqCeXKHpH67IoW01
	/mil/va1n0rTRVVHvNVf28BdaIka+ssAcW2t6o+4QFYQEVvt5/2aGEBDrSrPp7RarzwVymZsOzdV8
	d44cXFuuaLvw/9685kPVZrAGyvwnZo/fM/S7FkAMEj5EeqV/3TBpay0RrVLnx5B+C/H8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] x86/irq: fix infinite loop in irq_move_cleanup_interrupt
Message-Id: <E1kpALe-000607-9E@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:38 +0000

commit d785e076b36111899ef9ee2340f2da9375afc9f5
Author:     Roger Pau Monné <roger.pau@citrix.com>
AuthorDate: Tue Dec 15 14:14:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:14:34 2020 +0100

    x86/irq: fix infinite loop in irq_move_cleanup_interrupt
    
    If Xen enters irq_move_cleanup_interrupt with a dynamic vector below
    IRQ_MOVE_CLEANUP_VECTOR pending in IRR (0x20 or 0x21) that's also
    designated for a cleanup it will enter a loop where
    irq_move_cleanup_interrupt continuously sends a cleanup IPI (vector
    0x22) to itself while waiting for the vector with lower priority to be
    injected - which will never happen because IRQ_MOVE_CLEANUP_VECTOR
    takes precedence and it's always injected first.
    
    Fix this by making sure vectors below IRQ_MOVE_CLEANUP_VECTOR are
    marked as used and thus not available for APs. Also add some logic to
    assert and prevent irq_move_cleanup_interrupt from entering such an
    infinite loop, albeit that should never happen given the current code.
    
    This is XSA-356 / CVE-2020-29567.
    
    Fixes: 3fba06ba9f8 ('x86/IRQ: re-use legacy vector ranges on APs')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: ca85682e8c16361fdf3814c9b25a2ec3ff4f8bed
    master date: 2020-12-15 13:42:16 +0100
---
 xen/arch/x86/irq.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 8d1f9a9fc6..37c86283cc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -441,8 +441,15 @@ int __init init_irq_data(void)
     set_bit(HYPERCALL_VECTOR, used_vectors);
 #endif
     
-    /* IRQ_MOVE_CLEANUP_VECTOR used for clean up vectors */
-    set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
+    /*
+     * Mark vectors up to the cleanup one as used, to prevent an infinite loop
+     * invoking irq_move_cleanup_interrupt.
+     */
+    BUILD_BUG_ON(IRQ_MOVE_CLEANUP_VECTOR < FIRST_DYNAMIC_VECTOR);
+    for ( vector = FIRST_DYNAMIC_VECTOR;
+          vector <= IRQ_MOVE_CLEANUP_VECTOR;
+          vector++ )
+        __set_bit(vector, used_vectors);
 
     return 0;
 }
@@ -727,10 +734,6 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
 {
     unsigned vector, me;
 
-    /* This interrupt should not nest inside others. */
-    BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
-                 APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
-
     ack_APIC_irq();
 
     me = smp_processor_id();
@@ -774,6 +777,11 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
          */
         if ( irr & (1u << (vector % 32)) )
         {
+            if ( vector < IRQ_MOVE_CLEANUP_VECTOR )
+            {
+                ASSERT_UNREACHABLE();
+                goto unlock;
+            }
             send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
             TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY,
                      irq, vector, smp_processor_id());
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:26:50 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:26:50 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54115.93726 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALq-0005jt-3B; Tue, 15 Dec 2020 13:26:50 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54115.93726; Tue, 15 Dec 2020 13:26:50 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpALp-0005jl-W0; Tue, 15 Dec 2020 13:26:49 +0000
Received: by outflank-mailman (input) for mailman id 54115;
 Tue, 15 Dec 2020 13:26:48 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALo-0005ja-Eo
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:48 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALo-00079e-Di
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:48 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALo-00060u-D1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:48 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=31uIG7e5RlFdo+yDk4XEYKOnm9S2DjJma+3Rnr5yTXg=; b=Dyjj2/OloePchh2ahudgO9Q2G7
	M1wHK9gh4KOH9nV4gyguOhy9Ce+xFB7iqB65Qu4W31BG7Sepcr0u83Tc+y9XzEqywEdcGkTgkt/5R
	jn6kqDVLbClJ3ey9qgaBp1ABkpZoTPtZ5gaIZsxI8DVQFfvM9NWSKKIVEonPADsihAf4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpALo-00060u-D1@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:48 +0000

commit 9872981ddd8483190f5f634e289806ee047d3f5c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:14:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:14:54 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:00 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:00 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54116.93731 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAM0-0005mp-5c; Tue, 15 Dec 2020 13:27:00 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54116.93731; Tue, 15 Dec 2020 13:27:00 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAM0-0005mh-2Y; Tue, 15 Dec 2020 13:27:00 +0000
Received: by outflank-mailman (input) for mailman id 54116;
 Tue, 15 Dec 2020 13:26:58 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALy-0005mY-HE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:58 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALy-00079m-GZ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:58 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpALy-00061t-Fp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:26:58 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=H34YL/lTyAouokrJtLUolG3zLbtq47+zZV0Px1DYSmc=; b=1q+sv7HOf1mjzms16X9042qUdG
	FW2Kz53AMxjQ9eRaxasS+CuSLnFeWsNnMMpE3orJmjF1KKpXcd5qMY1vnbiKB/Am8McbD+5wUEp84
	yfL+9KukjuIpx/aKwHofB88L44QMug1xnctBX4yvFEKfc9w8x7WhvgdvTR0YrGpamXZ0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpALy-00061t-Fp@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:26:58 +0000

commit d17a5d5d2774601f8137984a3ee23ec28eb0793c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:15:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:15:13 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54117.93735 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMB-0005oC-7N; Tue, 15 Dec 2020 13:27:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54117.93735; Tue, 15 Dec 2020 13:27:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMB-0005o3-45; Tue, 15 Dec 2020 13:27:11 +0000
Received: by outflank-mailman (input) for mailman id 54117;
 Tue, 15 Dec 2020 13:27:09 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAM9-0005nv-R5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:09 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAM9-0007A9-QR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:09 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAM9-00066a-PC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:09 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Jq77c72xSQwsUcFrAu+r7ZjIKc3+L5583haVXAIy2DM=; b=UITgnPoaP1ZI4c0KXNzAEZRCiW
	KR4A20Ft1DEJaV+d0FI+Qu4PweE6Y0ob06f6u3SuxDO7tNWpkDSYn1mFX3XQUv8l7uTiB/klHEDq2
	ceA7FSRNWJ7PWpP6e/+SLtwz5qwvk4kwld0MDm6Wmy7/fOQ1wC3DFmjQ/qMyoPrNyYi4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpAM9-00066a-PC@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:27:09 +0000

commit 2fa586cb827737e08bf225521491bfd1aab18f22
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:18:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:08 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:21 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:21 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54118.93739 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAML-0005pL-8b; Tue, 15 Dec 2020 13:27:21 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54118.93739; Tue, 15 Dec 2020 13:27:21 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAML-0005pC-5b; Tue, 15 Dec 2020 13:27:21 +0000
Received: by outflank-mailman (input) for mailman id 54118;
 Tue, 15 Dec 2020 13:27:20 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMJ-0005p5-Uq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:19 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMJ-0007AF-TM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:19 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMJ-00067z-SX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:19 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DO3A7Y2ToeE0VrHisZ5CPV4T/BTCr37L8IhqW+NWCQk=; b=w1I2+8cx0hv+Szvreh6mRx5U0X
	fPwY0DbqlwG1Sq9gEnLS/LVOix23bXv23cwb2W5Q1O0ni/+lpHXafcGm9LAlY2k5HA+fHCKd1Iwv0
	BbR32Wc2WmpuAPAEw2CDEwiog28vo78Nea5tjtt8QWxH4WFao4xuApldm4CR39RvWN/A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpAMJ-00067z-SX@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:27:19 +0000

commit 4959626e926ce2e6de731135b1f567433edcd992
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:22 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 97ceabf964..b43e1018ba 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index c4c32bc88f..29d638fbc5 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:31 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:31 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54119.93744 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMV-0005qy-AS; Tue, 15 Dec 2020 13:27:31 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54119.93744; Tue, 15 Dec 2020 13:27:31 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMV-0005qs-7B; Tue, 15 Dec 2020 13:27:31 +0000
Received: by outflank-mailman (input) for mailman id 54119;
 Tue, 15 Dec 2020 13:27:30 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMU-0005qj-1m
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:30 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMU-0007Ah-0D
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:30 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMT-00068n-Vh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:29 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=weezQfskiUbvDZOly0a5tLQ5cVkv/17t+q+z+yxX7Es=; b=RD76a8ChlWQ/L4g5NOeMmmfgTN
	CvHo3hLdkckDiEmEWyzWtv9ccdBzxpRtXDJfQ/yUsDTUmf3F0pnVHubs2+oKrA2VOBkI1zswJw+Mb
	gBV8hvRGfvw2832gRpeGV1f1ME3nwgqGCrTKIYreuMQv9+1Raqiu7DyLOUEbDclD1I/A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpAMT-00068n-Vh@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:27:29 +0000

commit 2948458a63d4f65f17e348f68547a0bcffa1ee48
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:28 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b43e1018ba..bb2f9fd4e7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:42 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:42 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54120.93747 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMg-0005sJ-Ba; Tue, 15 Dec 2020 13:27:42 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54120.93747; Tue, 15 Dec 2020 13:27:42 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMg-0005sB-8k; Tue, 15 Dec 2020 13:27:42 +0000
Received: by outflank-mailman (input) for mailman id 54120;
 Tue, 15 Dec 2020 13:27:40 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMe-0005rv-3b
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:40 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMe-0007Ao-2w
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:40 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMe-00069P-2D
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:40 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yellICIc12gZF30DHjLC4tbBFjsV7nWCPIe2xXKyPYw=; b=Scdb4Jemr5RHz7ii5bUlpG0nPC
	34ysw8u3j//xPrgqcIvKHnJlYAlWebBftpZDsi3lu0W55UPUTHpaj6HBK0JDTgAbjN9oiAv8+a2Yl
	qHIrVw2i2Kuoa5aThXts+fFgIdGKe6oYPOvjh5eSQN7HVGXrXNVVyPxqs5bx+d5a0wE4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpAMe-00069P-2D@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:27:40 +0000

commit 2007c635cbf39351623e2fd0dcfa526184aff1e8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:33 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index bb2f9fd4e7..db9b9ca795 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:27:52 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:27:52 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54121.93751 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMq-0005tW-Dt; Tue, 15 Dec 2020 13:27:52 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54121.93751; Tue, 15 Dec 2020 13:27:52 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMq-0005tO-AI; Tue, 15 Dec 2020 13:27:52 +0000
Received: by outflank-mailman (input) for mailman id 54121;
 Tue, 15 Dec 2020 13:27:50 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMo-0005tB-7L
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:50 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMo-0007Aw-5g
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:50 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMo-0006A3-4r
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:27:50 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nn62iMlpwhL+UCTn1mHKS4fvVdFnm9IYm9iHcnjQYTE=; b=cn1K98Hx1RzveMrikTgHeT+GaC
	/DI/EBxvYRpl0H5LJ5brCy9/0TBgCy/xfXGVL1onHm68ECAHFUbTZGJi7OEvdBRBRvbKmBNe6xFYX
	BIqOnPUdDRI7H2zAll7XAc8CYl9Dw6LLns73MBv9Kz+6K4FiYLHGyl0+xTCaoquyRe+o=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpAMo-0006A3-4r@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:27:50 +0000

commit 1ab192f4eac9c264588723fa49137279bcafe780
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:39 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:01 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:01 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54122.93755 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMz-0005ux-H8; Tue, 15 Dec 2020 13:28:01 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54122.93755; Tue, 15 Dec 2020 13:28:01 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAMz-0005un-Dw; Tue, 15 Dec 2020 13:28:01 +0000
Received: by outflank-mailman (input) for mailman id 54122;
 Tue, 15 Dec 2020 13:28:00 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMy-0005ug-9E
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:00 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMy-0007B7-8U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:00 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAMy-0006Ap-7l
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:00 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LfGojzJvlGDSR+HpWfktGHkfwSjK/Z1UEmxw8qmRYwY=; b=0/7WF3g365mvznllhXCMRDMz1w
	MSHEmMjhtlIZn3ejsPHRd0/PRD/ZQjKeE4Yi5+CjO+y/LRwupfxr+qCKtP9CMSf9e4mV2TE5yeB44
	Wv/yFvgLlPaSXCv6TSICfMn5B9wRQjPKPBsmJNqaRg7XX4cEYA1eOegkT+KRQoffoQ+8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAMy-0006Ap-7l@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:00 +0000

commit 1819c9dbe8f93e832a18db61390948e35f5862c5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:44 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index db9b9ca795..6afd584311 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 1eae703ef6..0e2926e2a3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -377,7 +377,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -445,7 +445,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -480,9 +480,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54123.93759 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAN9-0005wH-Ix; Tue, 15 Dec 2020 13:28:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54123.93759; Tue, 15 Dec 2020 13:28:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAN9-0005w9-Fd; Tue, 15 Dec 2020 13:28:11 +0000
Received: by outflank-mailman (input) for mailman id 54123;
 Tue, 15 Dec 2020 13:28:10 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAN8-0005vz-Dl
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:10 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAN8-0007BW-CD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:10 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAN8-0006CQ-Ae
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:10 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=pA6F9VVH9jscpfzcAZM53NinFHPgWrn7jYBcF5bmnH4=; b=tyMF5bEUGmArVVAb3dUtGrOWLt
	1U1iFdIcuQVDN5dz5E9d7Xj8AoDF0IDWBAgLz2du3n7C8sX7xcmP0q73So+iJU1rJ1bHEBoZqdFru
	r/UgOIwfL3dHvGIUgyj1DGV9ZAcppFJvKUd2yh7wyt060WMaZER8CxbtagOSuiPKtr6U=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: rework node removal
Message-Id: <E1kpAN8-0006CQ-Ae@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:10 +0000

commit ee416da072f43268a1065bda6a80d09daf9efc1c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:49 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6afd584311..1cb729a2cd 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:21 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:21 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54124.93763 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANJ-0005xV-KA; Tue, 15 Dec 2020 13:28:21 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54124.93763; Tue, 15 Dec 2020 13:28:21 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANJ-0005xN-HF; Tue, 15 Dec 2020 13:28:21 +0000
Received: by outflank-mailman (input) for mailman id 54124;
 Tue, 15 Dec 2020 13:28:20 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANI-0005xF-HC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:20 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANI-0007Bj-GU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:20 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANI-0006Dy-Eh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:20 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FankK+5eeKXf+kBSiKRL+QTDCcAj8VYi/LVNsoYby3E=; b=dbYQCrFKioQMniKb5AbcRnCnzH
	oW8MVLf6ikmTkb4loGzk/O+ldFC3rhYl2n0oQSS71XVb52gXZ+7hymOH8jMPnsd2nne4dPrwFVc1P
	ERWhlRyd2BhLKXh+AMDFMW7tn2JkUCPDdKNL1CtU3L2pQSi4nX4aNOD2CyY4iMwtrUcY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpANI-0006Dy-Eh@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:20 +0000

commit b8f23da652610d3cc8a2d76740aa8d1f5d7d05ba
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:54 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1cb729a2cd..d7c025616e 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:31 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:31 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54125.93768 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANT-0005z2-MN; Tue, 15 Dec 2020 13:28:31 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54125.93768; Tue, 15 Dec 2020 13:28:31 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANT-0005yu-Is; Tue, 15 Dec 2020 13:28:31 +0000
Received: by outflank-mailman (input) for mailman id 54125;
 Tue, 15 Dec 2020 13:28:30 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANS-0005yn-Ko
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:30 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANS-0007C7-K5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:30 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANS-0006FI-Ii
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:30 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kUZIiXS3Z/qPyiKPeiDvBtCF25W3UGXLnTURwhuBTWc=; b=gmFW3NVaQXQY31cv2UiTxM4dTh
	HtAnj2R5jGrQ4kNxFevFB48jPdRXOPl5EcsoVaE0R7XPg6hGKOx6wJJvHM3jeGrwSVtgg9yJHth/+
	Zc7RZ8ZoArOKbZh45l36rLE19q5rRsXJP1Hiu0hU7+uO9hNw3LuOMmyvXclaZZM5+DSA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpANS-0006FI-Ii@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:30 +0000

commit ef765f6ebc3d67c02814f654c876fbd010f97792
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:59 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index d7c025616e..fe9943113b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 29d638fbc5..47ba0916db 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0e2926e2a3..dc51cdfa9a 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -657,12 +657,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -683,12 +683,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:41 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54126.93771 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANd-00060W-On; Tue, 15 Dec 2020 13:28:41 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54126.93771; Tue, 15 Dec 2020 13:28:41 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANd-00060O-Lo; Tue, 15 Dec 2020 13:28:41 +0000
Received: by outflank-mailman (input) for mailman id 54126;
 Tue, 15 Dec 2020 13:28:40 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANc-00060F-O2
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:40 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANc-0007CM-NJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:40 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANc-0006GR-MS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:40 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=f4uFisbERS5lUr8CXkazAsjqpMMeJsQg3KChZi/cPJE=; b=iqZNIfz+nPP5vF3yVN3CxUA55Y
	7vYoiXNztQInsDdHsmvozpRl+J5+Bi/kuxSucRrX5USJ3BpU9ii9uacF4FLOz2ToymwZmY25oqF8u
	6Ft5pVx+emCanH69rmUyLZ2UF2UCSZpWJOTGdCf8HE7by3kJUulBwcKe+Ctpwhb50z+g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpANc-0006GR-MS@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:40 +0000

commit 8cc0a86379f9b1544ab274bae69423c603d01b93
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:04 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fe9943113b..720bec269d 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 47ba0916db..53f1050859 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index dc51cdfa9a..7afabe0ae0 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -589,6 +592,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -610,6 +666,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:28:51 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:28:51 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54127.93774 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANn-00061m-Q8; Tue, 15 Dec 2020 13:28:51 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54127.93774; Tue, 15 Dec 2020 13:28:51 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANn-00061f-NN; Tue, 15 Dec 2020 13:28:51 +0000
Received: by outflank-mailman (input) for mailman id 54127;
 Tue, 15 Dec 2020 13:28:50 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANm-00061Y-Rh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:50 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANm-0007CW-QD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:50 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANm-0006I3-PT
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:28:50 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9tag7BleWQBAhXnwShJpowHD9LhlkQpvlqwlYIpxxWM=; b=6/H7P8nE17BP4fYeukEKfvzP1X
	LXWK4x6ZyGy3Y5DfLZziI2MGc32MY++wgU62NKnL0DmV39g72EDNEgY8fVZfB5A7Yu+tAukbh+qyU
	4pGk6Q999NzjZp2aaWErcub0umIRQQHnKp+5X3jHhcw5PdAxkoqBKgASUh7On7HsWX7U=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpANm-0006I3-PT@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:28:50 +0000

commit 60e3727bcae7268a57aa240c799b1bc788c9c39b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:09 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 720bec269d..1c28454545 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53f1050859..eb19b71f5f 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7afabe0ae0..711a11b18a 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -206,7 +206,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -244,7 +244,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -410,7 +410,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:01 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:01 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54130.93781 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANx-00063M-T9; Tue, 15 Dec 2020 13:29:01 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54130.93781; Tue, 15 Dec 2020 13:29:01 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpANx-00063E-Ou; Tue, 15 Dec 2020 13:29:01 +0000
Received: by outflank-mailman (input) for mailman id 54130;
 Tue, 15 Dec 2020 13:29:01 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANw-000635-Ub
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:00 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANw-0007Ce-T0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:00 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpANw-0006JE-SE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:00 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Xaq9i8Iwv/S8j9UekpATaPjJDouSZoj8gKs/5+QYTAI=; b=CQvOutavT6n4vhPTY4HsBUZuHA
	V1/HlBmRJ3+GV+94QtEbMJZMtnCTCKvRvXwU4I7rdjz6IcnQSdma6gGZJVadV+/kmobJ9TeLIC7S4
	zQf9kieICg9IKTX2aCVgmsxsnIh+BzzuZnnwCnMptEcvTho2DxFN5F8zq9yMfUkLdiao=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpANw-0006JE-SE@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:00 +0000

commit 52a0a8f6114e59753d761ea7c21552fc5370cc56
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:23 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54131.93782 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAO7-00064y-Tb; Tue, 15 Dec 2020 13:29:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54131.93782; Tue, 15 Dec 2020 13:29:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAO7-00064q-Qj; Tue, 15 Dec 2020 13:29:11 +0000
Received: by outflank-mailman (input) for mailman id 54131;
 Tue, 15 Dec 2020 13:29:11 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAO7-00064c-2g
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:11 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAO7-0007Cz-1Z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:11 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAO6-0006Kx-WA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:10 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vdJynBlOhy5lkbv7pLtfbafo7CLD+mH9alIiPjgfKQM=; b=skyA5f8tItHmIm2PceJGrRhby5
	sfyUwrz+/yAennNuO+VMzP3N3xoXSVlwI6xhK29W+bBOrds2pK4ZHDuIB5unKhv2+1bjIlrmz6blY
	GcFEMkQn9UEgwbloU/bKCaiRe+SeBh4Dk+N2BjitPsJgzALV8K+j0mbs3j1mHRxgPAZc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAO6-0006Kx-WA@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:10 +0000

commit b6939685484deef2b4fcdd5ca2084980544b55e4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:28 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:22 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:22 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54132.93787 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOI-00066v-0F; Tue, 15 Dec 2020 13:29:22 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54132.93787; Tue, 15 Dec 2020 13:29:21 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOH-00066o-Te; Tue, 15 Dec 2020 13:29:21 +0000
Received: by outflank-mailman (input) for mailman id 54132;
 Tue, 15 Dec 2020 13:29:21 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOH-00066d-5E
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:21 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOH-0007D6-4a
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:21 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOH-0006MW-3l
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:21 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DDFVTcRFCeYrjyx4vzJC83yRO4dsvLVjNM2HcT2GovQ=; b=riuJErEiPkL7kPduO4eE5juris
	0bogSEXuWFpnlJIwsXyguKOmZXg8G+So/WKEK061JORX6K2zDnPzb2L0NLWAhUJWk47CIGCEakNlX
	YrGWiFJeBr7jEC9crsTAkYGz3Tp9g4DFh7bcTGoCj3hs49ieDcpweFoIKCLjGd5rU07s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpAOH-0006MW-3l@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:21 +0000

commit 2df79ff3ec66d6e877e3100cd1429199b1a03389
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:34 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:32 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:32 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54133.93791 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOS-00068j-20; Tue, 15 Dec 2020 13:29:32 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54133.93791; Tue, 15 Dec 2020 13:29:32 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOR-00068b-VD; Tue, 15 Dec 2020 13:29:31 +0000
Received: by outflank-mailman (input) for mailman id 54133;
 Tue, 15 Dec 2020 13:29:31 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOR-00068T-85
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:31 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOR-0007Da-7L
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:31 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOR-0006NO-6Y
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:31 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ftd5CE6SGGCRMMEg7uaAY9DQ5clpaJ4MQJtw5wceS98=; b=yQQC3Za1TJ0iEB7NghEHkxmZ4N
	x0JEKVzMnExPFhtfEbQR9hXRYzs2izdIo6RTLg+BMZ/NMsQqQBRh0Oq0PO9HGOdz2MqLge4u6rax9
	R22mfUeO5rbw2pVGqr9vRlzsKD8Dw8FAgagg+QR0hB3Y192UmazL8fNO3Iw7SqFA/7IA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpAOR-0006NO-6Y@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:31 +0000

commit 65c187f935c0e616424760b01e22c7b713f0907d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:39 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:42 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:42 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54134.93794 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOc-0006AY-3Q; Tue, 15 Dec 2020 13:29:42 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54134.93794; Tue, 15 Dec 2020 13:29:42 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOc-0006AQ-0T; Tue, 15 Dec 2020 13:29:42 +0000
Received: by outflank-mailman (input) for mailman id 54134;
 Tue, 15 Dec 2020 13:29:41 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOb-0006AH-B7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:41 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOb-0007Dh-AL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:41 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOb-0006Og-9S
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:41 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BoVF58jd7+bOuJcxearJbJKsBidwByOmFvZPU5xBgxo=; b=mbtB7+MkTJa+dA9V/RJtqQb6Tn
	ujuXRKU83I86peARMHagQbAcjyjf+6cVY+1qJ7iKkWLByrP81wHP19gSvhPof6NjY4w6wryOWOavq
	dnMtprfLq3jL7NaYvWO4qdmdhDlYBLx6l3WLOjJkIIUqdYBfOU6td8KSflEhWhFg0dAU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpAOb-0006Og-9S@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:41 +0000

commit f4d84a2481baf1aab9937db88af9b72e172a4a6f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:44 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:29:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:29:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54135.93799 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOn-0006Bq-55; Tue, 15 Dec 2020 13:29:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54135.93799; Tue, 15 Dec 2020 13:29:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOn-0006Bi-24; Tue, 15 Dec 2020 13:29:53 +0000
Received: by outflank-mailman (input) for mailman id 54135;
 Tue, 15 Dec 2020 13:29:51 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOl-0006BW-Fx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:51 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOl-0007Dv-DF
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:51 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOl-0006QZ-CS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:29:51 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gp0uWyxhZja1omTbzSq5ciIkPNI3JzBAGPUpikL+Gic=; b=SgACaCpjgNoZCW5YCYshcHK3U6
	q+ZHdUbo+31WYSubn+hiyWXD0rPfCu3DzzvPJHlH/439jDL9VxhKxYR5g88rtkgiq4JUQBETgvqIO
	NH0NcU75hL0OUPru6l/O9jz444RrAAKOwVEuPw4z+L0PSBTE78pz0xVCSxfBK5xlom74=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpAOl-0006QZ-CS@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:29:51 +0000

commit 4056c3e6682ff8eea9fc4014648acfeb755a9e64
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:50 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54136.93802 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOx-0006MV-8V; Tue, 15 Dec 2020 13:30:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54136.93802; Tue, 15 Dec 2020 13:30:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAOx-0006M6-5C; Tue, 15 Dec 2020 13:30:03 +0000
Received: by outflank-mailman (input) for mailman id 54136;
 Tue, 15 Dec 2020 13:30:01 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOv-0006DU-HC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:01 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOv-0007ES-GW
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:01 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAOv-0006TF-Fe
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:01 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nqskahmo9RIBJPF164ynQJ9QtvUClKr/yud8SLtPsg4=; b=pjtcL3khOBFW4xQeXnyuE9I4Cm
	/Z7d7trajci9pYHjRStOI1D6Ujv3fe9hQej4PZTmMtHkEY7fnw4MzikWcUo0rt/9r7EzInSH1IX6p
	SfEmet5vNHbL9xsA8UJwOAQC5X9rlQFVN7FdG0m8rd1LAFC3uxFcSB2xZ1LmRuudS/As=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpAOv-0006TF-Fe@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:01 +0000

commit 12a41a8072a7fc75e58083c0d3bf55200d578bef
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:20:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:20:24 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1c28454545..cb2c70bfe7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 711a11b18a..2a02b22933 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -192,6 +198,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -213,21 +222,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -293,58 +315,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -391,15 +439,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -510,8 +564,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -654,8 +708,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -736,6 +792,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54137.93807 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAP7-0006vb-AJ; Tue, 15 Dec 2020 13:30:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54137.93807; Tue, 15 Dec 2020 13:30:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAP7-0006vT-70; Tue, 15 Dec 2020 13:30:13 +0000
Received: by outflank-mailman (input) for mailman id 54137;
 Tue, 15 Dec 2020 13:30:11 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAP5-0006vI-Lo
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:11 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAP5-0007Ee-L9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:11 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAP5-0006Tm-Ib
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:11 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=o1ZOBuAkijgjiyxUKjPA8rbnhZwhNgngW0VcZGPgK1U=; b=Vh1Owk0rkLmSxNq3lRQ99z9OvB
	x0YGgmhZjDueulH1lDOhzUUC7l1kNugY/ounLD2qy19MnXcT3P2zUaoKMBem1UaqdKsBTWUeqOUi9
	DBT3u4DXOcxH0reGJMRSMRXMqoP0cZ8mlX8EAWofoWs1MD8W7W5EXKfmIlZkebYTqOds=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpAP5-0006Tm-Ib@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:11 +0000

commit 6aea4d88cdb3a403f373d270002d88d2881a94ae
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:20:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:20:30 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..a194cbc76f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54138.93811 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPH-0006xX-CG; Tue, 15 Dec 2020 13:30:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54138.93811; Tue, 15 Dec 2020 13:30:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPH-0006xN-8m; Tue, 15 Dec 2020 13:30:23 +0000
Received: by outflank-mailman (input) for mailman id 54138;
 Tue, 15 Dec 2020 13:30:21 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPF-0006xB-PQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:21 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPF-0007Em-Oj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:21 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPF-0006W1-NQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:21 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QKMg6cN2W2UQlfPP/MArcTOYovX3XTbZqe5N1PdceP8=; b=yfpDLoPkqreZ9FBa/DEjPpRY8p
	xKF7UkNeQ/xNSCpSZFXhpKTDGlROzdnW0l5QW9guIwK/iS8Ugz3byanNfCt0KDCTmawGQqo7TDvRe
	GJ93Kn/5NviNjcp0bYacSFl0pLyJGcPNIoRWYUxWEVCzRswVzUjIJUBaogBjvy+RPrg4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpAPF-0006W1-NQ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:21 +0000

commit 782aa4bb53145ebeadaf1dfa448d1dab144fa6d9
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:00 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a194cbc76f..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54140.93815 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPR-0006zh-Eb; Tue, 15 Dec 2020 13:30:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54140.93815; Tue, 15 Dec 2020 13:30:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPR-0006zZ-Bh; Tue, 15 Dec 2020 13:30:33 +0000
Received: by outflank-mailman (input) for mailman id 54140;
 Tue, 15 Dec 2020 13:30:31 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPP-0006zL-TJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:31 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPP-0007FD-Sf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:31 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPP-0006XD-R9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:31 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FV4YEY+mcjU9hJealbxWTMuOxgwshgosXjUdB2+Rq5s=; b=sTnJn2rlKM1X1QV6Ybx/1ZnAEL
	+G92IxQcSzV0NLZ4JSoHlz4SKDnou7nWXJpN1E3M4aRhY9rg3FVaeEJhmVm+iKjtZO3ppQZnTSHhM
	1r8oYn+ADLDUnWaAOcx37Nfdef3kKt4DcjawptRDIMqUd3Xql7VmEX0au/ud8ok46WE0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpAPP-0006XD-R9@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:31 +0000

commit 18c0abb8f77be8ffbe5e02a6e9a4aec7c39a1d41
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:21:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:04 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cb2c70bfe7..407e665755 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54141.93819 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPb-00071V-GB; Tue, 15 Dec 2020 13:30:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54141.93819; Tue, 15 Dec 2020 13:30:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPb-00071N-DA; Tue, 15 Dec 2020 13:30:43 +0000
Received: by outflank-mailman (input) for mailman id 54141;
 Tue, 15 Dec 2020 13:30:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPa-000715-1z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPa-0007FL-1D
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPZ-0006Xw-W3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:41 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=U0JMYJYGiBjDIbtqUuxafB0ihR/YVCWGXETOzdrMSdU=; b=L+s7J5nOMgCOg0tLc9IuELhmkU
	u0Uj73cUrVy3DMeMKxIgxrl+Q+4m36UUsPTS1X2D8XmXng1SsVS4sWnHoEGpLVfrSCSmKSKeBQrXM
	12IWCM68SIjulSdMwQ1MfG30UZDDXF/bxHhh05h0xpi/zs6IB7zOKxL3sLpDikTlK7dQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpAPZ-0006Xw-W3@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:41 +0000

commit c6196caf012cd199d254526e2e8613385a0db7e4
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:21:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:09 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 407e665755..08190ecc55 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index eb19b71f5f..196a6fd2b0 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 2a02b22933..cbd8e6b747 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -290,6 +290,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -307,6 +311,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:30:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:30:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54142.93823 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPl-00072z-Hq; Tue, 15 Dec 2020 13:30:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54142.93823; Tue, 15 Dec 2020 13:30:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPl-00072q-Ef; Tue, 15 Dec 2020 13:30:53 +0000
Received: by outflank-mailman (input) for mailman id 54142;
 Tue, 15 Dec 2020 13:30:52 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPk-00072c-6Z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPk-0007FV-4z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPk-0006ZE-3O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:30:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0wQZkhNOBhGoXbgeGaseSRUNM8dEJViuLQjVb7f6svg=; b=6K9ypCW/+p1ZNt1ehqKvQ4MEfE
	IuVP4csWDgf3KpZYg0pdWC20ZK4qSBNbO8syximQtxQWGDWmYgBnrux2YFqek9BgSNIwnn1oY2m0S
	FOlXWVu7EFW/na81w4KxhuQLf6PtmlI0GeqdYgFcp8Oc767Xr/CwPNCTkePlzpMfnA7Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpAPk-0006ZE-3O@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:30:52 +0000

commit d6a55f1c676ee4b0b43dfa5c2365383c017ae791
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:23 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54143.93827 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPv-00074m-JD; Tue, 15 Dec 2020 13:31:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54143.93827; Tue, 15 Dec 2020 13:31:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAPv-00074e-G8; Tue, 15 Dec 2020 13:31:03 +0000
Received: by outflank-mailman (input) for mailman id 54143;
 Tue, 15 Dec 2020 13:31:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPu-00074R-9P
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPu-0007HQ-8E
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAPu-0006a7-6x
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GFvSwbzirwGXUgOxwSlsrpeB+DnkP/L3w9FBcT1FX2U=; b=mewia13kz3FHfU0HO2K5VjEKQo
	+0B3hYOXus/dPRP9tl0woGzTEf2N80ZgfiIJLuz74UzcZTPqdMbKeQ2wBJQILkii1D0WrzcykwFp8
	Dpa0q39xuqR0Du1i7KarhN23Ln4My0s05Vpkfr3quAItVzlhz807Akfelb2ZUABUfS0g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpAPu-0006a7-6x@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:02 +0000

commit a2f7ae132da97de094754a2122a8f23567b610e0
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:28 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54144.93831 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQ5-00076Z-Ki; Tue, 15 Dec 2020 13:31:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54144.93831; Tue, 15 Dec 2020 13:31:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQ5-00076O-Ha; Tue, 15 Dec 2020 13:31:13 +0000
Received: by outflank-mailman (input) for mailman id 54144;
 Tue, 15 Dec 2020 13:31:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQ4-00076A-CK
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQ4-0007HX-Bg
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQ4-0006b6-An
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BpQs370h/oI1zygwXc9kkri46+3A4XTexAO++UGX1h4=; b=juUdoT6ms26mxlc3TfssH4Bh4p
	ummbtDFbrZgUNsuSMC8WRObfCj8AY75dc2ng99JRBDeSinsewI4QUai2o+cUBbeR5WrqeWjP2yRNO
	9EhU7lGqkc4cpkfX2n3Vy2oZk4OjMttWzuq0NeV1FXz9/fkjpYvMmHVc8NgpU7mFqu2k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kpAQ4-0006b6-An@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:12 +0000

commit d39eb6fbb3ef0ef72f2fa88c9710e1416bc3a878
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:22:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:22:22 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
    master date: 2020-12-15 13:40:27 +0100
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 135c6d5b82..f4f55d0d84 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index fb73319cae..1f7b26151b 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1032,7 +1032,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index d53eceb23a..f10f6b78ec 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1889,7 +1889,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index aea8d6b2b9..efaa2e7abf 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -61,7 +61,7 @@ custom_runtime_param("pcid", parse_pcid);
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index ae61e93024..cc7274eae6 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -631,7 +631,7 @@ static void __init noreturn reinit_bsp_stack(void)
     stack_base[0] = stack;
     memguard_guard_stack(stack);
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 1f89984c9a..bace2da70c 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1300,6 +1300,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 0b47485337..d930b79404 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -129,22 +129,16 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
              "jmp %c1"                                                  \
             : : "r" (guest_cpu_user_regs()), "i" (fn) : "memory" );     \
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54148.93835 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQF-00079I-Mg; Tue, 15 Dec 2020 13:31:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54148.93835; Tue, 15 Dec 2020 13:31:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQF-00079A-JH; Tue, 15 Dec 2020 13:31:23 +0000
Received: by outflank-mailman (input) for mailman id 54148;
 Tue, 15 Dec 2020 13:31:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQE-00078p-Fk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQE-0007Hg-F6
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQE-0006cD-Dp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9cux2JMJd1tfk1MRf7+RZm6FODjjoT3gNBg+PDBY3Aw=; b=GUYS0xxO7CEH3XAdZXDlk+JX5f
	CcdZvkxaeskgX7Si6Mf6AWabOenhnwUW29C8ktbp2nmlw7J4ESGTuQ9I27Ihn39pnAW+NJOQcMvUc
	KKp9DgmcRlT5Aq3My84ui5XBFQik01Ey4RNidi0FL737cVeqVNGQQ8TugwhZlQ1/bi9Q=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kpAQE-0006cD-Dp@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:22 +0000

commit 13afcdf6f4c71d72c3d1fb31c24192ba8169f52e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:23:05 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:23:05 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: 058e469ab4d5cc5959423aafd6ba181dfc310a7f
    master date: 2020-12-15 13:41:09 +0100
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index f4f55d0d84..406f889880 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54150.93838 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQP-0007Bm-Q3; Tue, 15 Dec 2020 13:31:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54150.93838; Tue, 15 Dec 2020 13:31:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQP-0007Be-NB; Tue, 15 Dec 2020 13:31:33 +0000
Received: by outflank-mailman (input) for mailman id 54150;
 Tue, 15 Dec 2020 13:31:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQO-0007BV-Iz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQO-0007I6-IH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQO-0006d6-HR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4/ef+qRT29q9lRz6LKokpfF3f+1tIaLsBA2zTPKpXG0=; b=1K7aTCVfiXLkjmaOTz0Gd0KwS/
	Dt4ZLfF61Aosrpiy/S1ziXQbeoARzhGswU6EVUbYyoa6yfvGFllDs+Rh1780TErIdH06Nt2ei3sSF
	V/k62EQdstusEAD94XZVopdQ5ORh/s3Rn/pvxFAQNKKRADdk6bbnASW7XJpLe5JdyBj8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpAQO-0006d6-HR@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:32 +0000

commit 16d0dc0edaac18d7e269324b183ddccdcf8a5e94
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:23:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:23:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 406f889880..820cb0f905 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -535,7 +530,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1833,20 +1828,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 1f7b26151b..a6de9ccb8f 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -987,8 +987,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index f10f6b78ec..f3bd7f9bee 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1830,8 +1830,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index efaa2e7abf..f2d66b479e 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index d930b79404..a11d15cecb 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -129,16 +129,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (fn) : "memory" );     \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 1cd8743d11..309b56e2d6 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -313,7 +313,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 371b912887..591c598030 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54151.93842 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQa-0007D3-Rh; Tue, 15 Dec 2020 13:31:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54151.93842; Tue, 15 Dec 2020 13:31:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQa-0007Cv-Or; Tue, 15 Dec 2020 13:31:44 +0000
Received: by outflank-mailman (input) for mailman id 54151;
 Tue, 15 Dec 2020 13:31:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQY-0007Cm-M7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQY-0007IG-Kx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQY-0006dq-KG
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9PSLA5qZPHNg9rqzsnYGoVFhUeN/99znG8nOZO/o7yY=; b=1tv85Na1dtTYL32G1QPwEiCPMi
	WwWacxmAOoZ/pD9jTjbIDFkN4x3vxCbm47ISDpiBa6QSi1NLwtFAKHqo4VKAz3ioyFLcNXYp4bdv1
	bk6p5LQL3YvvpqnjNzZotivhN7mrOPTsEQJvDKv9jpcT50tgQrsVAZ2w9OT+acZh8/Nk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpAQY-0006dq-KG@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:42 +0000

commit bb534d6515080770178b6b750d1cb96968debbc6
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:24:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:24:19 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:31:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:31:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54153.93847 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQk-0007Ft-UC; Tue, 15 Dec 2020 13:31:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54153.93847; Tue, 15 Dec 2020 13:31:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAQk-0007Fk-QM; Tue, 15 Dec 2020 13:31:54 +0000
Received: by outflank-mailman (input) for mailman id 54153;
 Tue, 15 Dec 2020 13:31:52 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQi-0007Ea-Oe
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQi-0007IO-Nr
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAQi-0006fO-N5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:31:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Ab2IMBvhno51cTf8O/JTT9xjCljt7YbLJoanoXh/MIY=; b=NiP/8mkkWril5EeceC8AcSb9/5
	N+85lx4yg4CPIihCkZBF8/+OJ8XlECfrg51V37WjqsE6Mautl51+N/u+onrp8i1nsPLe9H4Eygjyb
	CqJIG5LSNFyxEsYGy7wKb1bvPrlWZaAq5ZC0K7STE6h4hazgAkWUd9yRREAE4k6kg0uI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.13] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpAQi-0006fO-N5@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:31:52 +0000

commit 10c7c213bef26274684798deb3e351a6756046d2
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:24:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:24:48 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54163.93863 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAcY-0008P4-1s; Tue, 15 Dec 2020 13:44:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54163.93863; Tue, 15 Dec 2020 13:44:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAcX-0008Ox-VK; Tue, 15 Dec 2020 13:44:05 +0000
Received: by outflank-mailman (input) for mailman id 54163;
 Tue, 15 Dec 2020 13:44:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcX-0008Os-5z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcX-0007VC-48
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcX-0008B2-2D
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=E7uCK2+2zI8KiYhwA1XeGOWIW+FzcydgGRJkEfdezTQ=; b=WfFsiac+ExW4S8vHCwSGpKVobi
	cj8tOVPydYkHoIa8KgKmbQItycXXUsNYxm8FTApUnVAo7u3qFxBGrQf1D+Y9EEC7X6uFIb8INXios
	oCbGn97STPlDpjqWGav/eG5C/eVEqVp5Np4zKtOrB5N8gHoOv+v1zx1pIlnoSo9+YynU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpAcX-0008B2-2D@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:05 +0000

commit c64ff3b47e44b2a31d04288c5e16059aee8c877b
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:27:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:27:28 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54164.93867 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAci-0008Pw-3v; Tue, 15 Dec 2020 13:44:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54164.93867; Tue, 15 Dec 2020 13:44:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAci-0008Pp-11; Tue, 15 Dec 2020 13:44:16 +0000
Received: by outflank-mailman (input) for mailman id 54164;
 Tue, 15 Dec 2020 13:44:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAch-0008Pj-8M
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAch-0007VI-7X
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAch-0008C2-6W
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cch4EV8tyP9eEwnofZsIg+5Mygshu6wlQEpLKL9Q4wQ=; b=evWcgt9sK+OY86S2ZJHYID4sr6
	QuHWVAoDG2JIXMY6Z+rCVfCJv3zoX7Z3C4MdWQGf91RsoC7j2z1piCiVbCcBiioxIHQRRCkKyGXfW
	8f4U5WVX6z+W2jhXi9lrVxCTS26MyIUEKOii0yuXLfvA/akGaempndUZkrTFqzTlJ22w=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpAch-0008C2-6W@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:15 +0000

commit 544a775f8ec48696b3a5207f075d74127d788df4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:07 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2146f35a6f..a5a71261bc 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54165.93871 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAcs-0008Rt-6y; Tue, 15 Dec 2020 13:44:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54165.93871; Tue, 15 Dec 2020 13:44:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAcs-0008Rl-3p; Tue, 15 Dec 2020 13:44:26 +0000
Received: by outflank-mailman (input) for mailman id 54165;
 Tue, 15 Dec 2020 13:44:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcr-0008Rb-BJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcr-0007VS-AV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAcr-0008DS-9b
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=CBNrPWZbfeMWRoquv3ZBd7v0t5YXTbPnwzkTmbRzUc8=; b=gld+WNEhJRQBc+xe7wMsyvSPUZ
	O3M5nxVUKrnBL2hoZZoWjCAsjghlSQLKK1ZC4LpS3BcrBuxdkioe4txMNjA5sgEjvSOL3JkjZqSlr
	xHcN3/ZviulalcyGE1KtmuPkkK7GfqmXUXIOFEmCxj8oxmJU+vt+q9DzkRv/vvrI2Vn4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpAcr-0008DS-9b@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:25 +0000

commit 444b7173db0a45df6c2e3dd3f6a58898e8638de3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:12 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54166.93875 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAd2-0008TE-8Y; Tue, 15 Dec 2020 13:44:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54166.93875; Tue, 15 Dec 2020 13:44:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAd2-0008T5-5I; Tue, 15 Dec 2020 13:44:36 +0000
Received: by outflank-mailman (input) for mailman id 54166;
 Tue, 15 Dec 2020 13:44:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAd1-0008Sx-JV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAd1-0007Vv-EP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAd1-0008FO-Ce
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1ND8Xvdn+6vlC4F/OYGfUiTDz9Lcvy7FK+dqwDlZArc=; b=poCE6Cwy0qYZ1AFNGeNio8/tgu
	khDxhxZJ9s6lnOZRmFUbN+OaKKSKrN0t0Y3UDOLgvSr5tpCGCcK8Pu7KWXJdPvs05i9qyLon+hf2X
	5dtwan4QkXtK8o9fZMIkOJLDck6as7PGO1kFdsfbWF/CKmOZRBLGTlizPnoQY7NvMAds=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpAd1-0008FO-Ce@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:35 +0000

commit 0dbcdcccbc66395179103c8063ca7008f06437e5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:17 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54167.93879 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdC-0008UW-A0; Tue, 15 Dec 2020 13:44:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54167.93879; Tue, 15 Dec 2020 13:44:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdC-0008UM-6p; Tue, 15 Dec 2020 13:44:46 +0000
Received: by outflank-mailman (input) for mailman id 54167;
 Tue, 15 Dec 2020 13:44:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdB-0008UE-Ji
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdB-0007W9-Iv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdB-0008GY-Gd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HVtCpje8q4clsZ07hm5eTREHYOquD10XkWitiNSOj/o=; b=NxG0A5jpKPq46SpmkLbK93ooFt
	CLK1Uxz4yc1a5oA8eBwyfwZHU42IgjGmuZHCaSipBrFrK5nKNcEkQHkuyw8/70Z4ZOB3uhj5peXVY
	wfKKvMAW7n6t3Rl6ksBhBKoIzeOi3g3xJMXtGgY6r53dSYe3rJFbbqGDw+nAglzPuqnY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpAdB-0008GY-Gd@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:45 +0000

commit 4739f7941a0c547b26e8ef914ee7b2569f15386d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:23 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:44:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:44:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54168.93882 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdM-0008Vm-BQ; Tue, 15 Dec 2020 13:44:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54168.93882; Tue, 15 Dec 2020 13:44:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdM-0008Vd-8F; Tue, 15 Dec 2020 13:44:56 +0000
Received: by outflank-mailman (input) for mailman id 54168;
 Tue, 15 Dec 2020 13:44:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdL-0008VV-N7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdL-0007WH-MP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdL-0008Hj-Kx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:44:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ap+3N5VOAPhKFTjzc2+/xwC22FKno1TNPuItqDVpjPc=; b=Lvzth2WcIcFcTJXMdPUB+rGs3n
	s6eHxib0m/NfZNxNudHoOdKL/IieJe8bItrPf8sFd7XIiAMNvAwi6uxg8Rzw+C6yLqKa/orGEnmdS
	tpGSFXGlgOEhZup+K7CKMj1OB4iKR/nL8zU35OC0r/uCXYGunil7PzmCy65o8J/nST2I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAdL-0008Hj-Kx@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:44:55 +0000

commit b1efedbec5c721186536db1a7a4d116526e4afdf
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:28 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54169.93887 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdX-00005W-D9; Tue, 15 Dec 2020 13:45:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54169.93887; Tue, 15 Dec 2020 13:45:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdX-00005N-9r; Tue, 15 Dec 2020 13:45:07 +0000
Received: by outflank-mailman (input) for mailman id 54169;
 Tue, 15 Dec 2020 13:45:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdV-00005C-Qg
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdV-0007Wp-Pu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdV-0008KW-Ok
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oRWGmJEPVNrvNLbPLn9j9BC11W5JCvYW5BtRTRgNpQg=; b=4DSSJjqWWTwcxzwjktbmVQsweH
	NEOPcCNFbBC/4Pq5PCaEXcPtT9+lPPLj0rdPyBkElJMNCj+25UvsUTqU27YPEnbYCWrpL5tg4wVr0
	+JqQqAcXzUgJG8ArAXRRop6zLN/lKYBLsSD8S5wMnkM1gOMnPXVmxw3qguV8ovC96GXQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: rework node removal
Message-Id: <E1kpAdV-0008KW-Ok@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:05 +0000

commit f1a4126a04d75ac43f223586751a2b163ddb5740
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:33 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54170.93891 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdh-00006y-G5; Tue, 15 Dec 2020 13:45:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54170.93891; Tue, 15 Dec 2020 13:45:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdh-00006l-Ct; Tue, 15 Dec 2020 13:45:17 +0000
Received: by outflank-mailman (input) for mailman id 54170;
 Tue, 15 Dec 2020 13:45:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdf-00006V-VL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdf-0007Wx-Ud
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdf-0008Lz-Sn
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LBMNgWczgq1YHIWZT3zgqwxMJsF3j43RL5w1k3we8S8=; b=2nG7Shkz9GfYg90OjYDtx+lNpF
	0zc8kGWYqMY/6obkuY7ZfVIa+9PycOJlHJ5AKedroh9J0lkNc2MGWq+TdWEVHtug0Q1lenyTnRLQf
	a9iEetF1NXPzckkRPc52rZcPo5rLgwqN9q4F30cgmo79eWPdlbH8J8BulXb/VkcN5mos=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpAdf-0008Lz-Sn@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:15 +0000

commit aeebc0cf05944557d0ace7db27793bd1d52fc3fe
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:38 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54171.93895 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdr-00008g-Hy; Tue, 15 Dec 2020 13:45:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54171.93895; Tue, 15 Dec 2020 13:45:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAdr-00008Y-Ec; Tue, 15 Dec 2020 13:45:27 +0000
Received: by outflank-mailman (input) for mailman id 54171;
 Tue, 15 Dec 2020 13:45:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdq-00008M-2F
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdq-0007X7-1W
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAdq-0008NL-0b
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LoIfOp6sqsjj4/dgOafLDVFo1vVAHTxOvo1wW4LtFbM=; b=wal6HhNWMKmN7CrGlCeqorxmIA
	uloYm2/CNmVgMFfnkhbFOJVYcN/TOC+//8rK6T2f/l8D8RQLViXmshoYUvPbuZzwmLOG42d0C/o4I
	q2GKEb3+w9eyUJp2hsp/xIVFEr2E4z6IC7QVwvGdEZi79Asax4eMYKm+IY0YQ8GDde5s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpAdq-0008NL-0b@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:26 +0000

commit 9f730200903b7dd663b173233cbb5c2650c4b558
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:43 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a5a71261bc..ed3b4c7266 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54172.93899 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAe1-0000A2-JH; Tue, 15 Dec 2020 13:45:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54172.93899; Tue, 15 Dec 2020 13:45:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAe1-00009u-GL; Tue, 15 Dec 2020 13:45:37 +0000
Received: by outflank-mailman (input) for mailman id 54172;
 Tue, 15 Dec 2020 13:45:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAe0-00009f-66
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAe0-0007Xb-5R
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAe0-0008On-3l
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Ka8qOD2f8qS2DzFVHD3+OHTPLvb6+z0AHj/1w0kmgTs=; b=lsta0tkpp8JAfOP5fj6a+3OW4C
	TXELIoMjk+jiiiV8CKrYXPBLHdx0loqmbxe44w6xb6r7DHFKbWu7uawL8atfx3P/lrtanAz/7Bgze
	YD2ic0qYthzcTTPIj5+DltLAI7xkkn/5OCOCCpGJ5gPI9qso4NZj4FLxlAosSp+yGHTw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpAe0-0008On-3l@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:36 +0000

commit f860f42a41a6ab08e1bffa69b21fe69ba7cca560
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:48 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ed3b4c7266..44d10e7b88 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54173.93903 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeB-0000Bh-Lq; Tue, 15 Dec 2020 13:45:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54173.93903; Tue, 15 Dec 2020 13:45:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeB-0000BZ-Hy; Tue, 15 Dec 2020 13:45:47 +0000
Received: by outflank-mailman (input) for mailman id 54173;
 Tue, 15 Dec 2020 13:45:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeA-0000BP-9Y
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeA-0007Xj-8T
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeA-0008QJ-7h
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KF+lWInXCJBHOWfKYyseyUqmWTZF2y0jvF1pnIDy2dw=; b=EHp/gFw5VuOacAl0OLpQdCk7OM
	MJAdQud1E684DisBbb7cZGR2zMHFltFlAMa5DOvie7Jcci75e0kn4JkkI0s8MPjYC4SXSOP4RNwHL
	YEbHG+K+prbz+u8JBRaMoPVJZnUn5U0ZFo3p6gU6cuJWDlQ+Yj1j0Zg6JoppCIC7u9sk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpAeA-0008QJ-7h@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:46 +0000

commit 655190de12e70ccba2107c643de1c527053b0fe8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:53 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 44d10e7b88..897ddab1e2 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:45:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:45:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54174.93907 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeL-0000DF-Nz; Tue, 15 Dec 2020 13:45:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54174.93907; Tue, 15 Dec 2020 13:45:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeL-0000D7-L3; Tue, 15 Dec 2020 13:45:57 +0000
Received: by outflank-mailman (input) for mailman id 54174;
 Tue, 15 Dec 2020 13:45:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeK-0000Cx-Bs
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeK-0007Xr-BE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeK-0008RL-AU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:45:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sOCfA5xm+RzhCmy/rWZ+J0liDZzcjjAqLPbfDX3jeoE=; b=Yn/Kr+38HpD9nm7a6GyH0mDdYp
	dq+SaWQXYi71dMnhkx5cM/C7u4Y6YxDzuPXxwAmLfFDRr4N6qvOMABRjHpWdBiYmHD1SZIiqCnm56
	0759ukqa7+DEBXJzz9WAqdoYlfS9SFEZcSu7FWuLe3ia8CBaVl/JIQfmFm7WaeZCOJ5I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpAeK-0008RL-AU@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:45:56 +0000

commit f8443e804c2ab0ae0f8fea7df00c0d51da2f34a1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:28:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:59 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 8a7e538893..fb0a6d47c3 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54175.93911 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeV-0000Ea-Pk; Tue, 15 Dec 2020 13:46:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54175.93911; Tue, 15 Dec 2020 13:46:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAeV-0000ES-Ma; Tue, 15 Dec 2020 13:46:07 +0000
Received: by outflank-mailman (input) for mailman id 54175;
 Tue, 15 Dec 2020 13:46:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeU-0000EG-Ed
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeU-0007Zn-Dx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeU-0008Sp-DB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8ULb77DUP5Glw1J5KMsYv8wOA6e8L/xwfoAlr6dpriY=; b=D51BFR11Q9EhdopReLItBWvihn
	yfTNg5qH9Ew25NPIlC1maP/nLFVh4k4quYYSPnFunbxUjrzX2e11F9dttNEvGF51xWhI0H/t91ESh
	9+ECyTjOx6H1Z5d+sRNt/kqWVzcxjF/6TC/zJZ5stwAHks2tMb0LlxC/LbAjzK4x50kI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAeU-0008Sp-DB@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:06 +0000

commit 5e1bac4a10d25a71a868fda7f4c12f9665d694db
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:04 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fb0a6d47c3..56aea4ce30 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54178.93915 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAef-0000GI-RM; Tue, 15 Dec 2020 13:46:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54178.93915; Tue, 15 Dec 2020 13:46:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAef-0000G8-OF; Tue, 15 Dec 2020 13:46:17 +0000
Received: by outflank-mailman (input) for mailman id 54178;
 Tue, 15 Dec 2020 13:46:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAee-0000Fn-HR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAee-0007Zv-Gj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAee-0008UP-Ft
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=t6Ei7hE6/DmnGbfeuGvINxp72IlPziZjrMKPnFv3nlo=; b=A38NRLZaq6j0EuoNEpcIKdy1J1
	nUV1dWwslE89CO6kMVc8WAQPl3IocXrH0bRMeaOBJw2ddWcSYcRxRUxrUDLVHtyy10ty/ezpMzL4R
	ke3YIpbJDmPiAorpDdXxiAmdEmnzA3vcQOX9rMp3Qn1zCw4+XkxWFDtxg2Y0lMPenmSQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpAee-0008UP-Ft@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:16 +0000

commit 551d75d1ff56b7a40c794923c440db7b02f6c207
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:09 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54180.93918 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAep-0000Hr-Sy; Tue, 15 Dec 2020 13:46:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54180.93918; Tue, 15 Dec 2020 13:46:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAep-0000Hj-Px; Tue, 15 Dec 2020 13:46:27 +0000
Received: by outflank-mailman (input) for mailman id 54180;
 Tue, 15 Dec 2020 13:46:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeo-0000HZ-Kk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeo-0007a4-Jz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAeo-0008VU-Iz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WGFB3SljSQ5ajR4fu2PjwVySJskW7W7wOXfnQbkPPyQ=; b=tHbZlD/NIpLdoETogtr3Bagkd7
	4wns00uzIidPBQ+SbpuGmKsT96CeczxHeImaWwVKAYu7MQooGZUjvpQ0vRhehNMERVEF4YvhcFdrq
	QjoaGB1Lxp6pECuVWfUIZVJQqdhzN6ZmiS4TgRB4Fb5UOdEMSqX8IUImpvZF3jtl0hCo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpAeo-0008VU-Iz@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:26 +0000

commit bfda5aefa1dfd359136465bf0c0ffacafd080c3e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:14 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 56aea4ce30..e42460f60a 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54181.93924 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAez-0000JI-VV; Tue, 15 Dec 2020 13:46:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54181.93924; Tue, 15 Dec 2020 13:46:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAez-0000JD-RY; Tue, 15 Dec 2020 13:46:37 +0000
Received: by outflank-mailman (input) for mailman id 54181;
 Tue, 15 Dec 2020 13:46:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAey-0000J1-Ns
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAey-0007aS-N9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAey-000058-MO
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=MQ4sEk6Gj5FWxFN8XpBRf02G096cljweAUf+nfU6UwM=; b=CVfmraw1MZqKGm7fcbwwUkdrP4
	q4GO8EXx0T5mJlt3OMwStw2qVNansf4Deszlu2tD2afDvj++Ocq/LGglEp740NeyTIAM9l5iEtSvF
	goRSAxiiPGQdsNJkhTOm6O6URkdRhTg1LEB6x+ZcKdJeCQlS7062juJxGCEatzTBRWUQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpAey-000058-MO@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:36 +0000

commit 674108e2207b37584f7129d6f195599dfc20dc01
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:19 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e42460f60a..5e2347d085 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -414,14 +419,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -433,7 +438,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54182.93927 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfA-0000Kl-2P; Tue, 15 Dec 2020 13:46:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54182.93927; Tue, 15 Dec 2020 13:46:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAf9-0000Kd-VQ; Tue, 15 Dec 2020 13:46:47 +0000
Received: by outflank-mailman (input) for mailman id 54182;
 Tue, 15 Dec 2020 13:46:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAf8-0000KT-Rx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAf8-0007ac-RI
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAf8-00005z-PM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ksFo7WWTAK/Ek40HTpIObJGdyoq2AxaKrCT3oBwlx1E=; b=T6pKohMDuQMUsZ3/HWr/mnFRPi
	lEyy4agDCfnNnxJ8P6Ui41/v6hvloJt8VfT6RJWmdRDDrFopWrxyWfCzRl+X4u465EbY/2nUTgC+U
	OPwKmVXktSwt2cngASZgoRtqAbTYazLc9CfTBwBZL8PvgsU3/vKRnj4D2xXsjzvGKtWs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpAf8-00005z-PM@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:46 +0000

commit d009b8d94eaecb8560a4db132c3f39f96877ac41
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:24 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:46:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:46:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54183.93930 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfK-0000NX-3k; Tue, 15 Dec 2020 13:46:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54183.93930; Tue, 15 Dec 2020 13:46:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfK-0000NP-0h; Tue, 15 Dec 2020 13:46:58 +0000
Received: by outflank-mailman (input) for mailman id 54183;
 Tue, 15 Dec 2020 13:46:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfI-0000NH-Uj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfI-0007ak-U4
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfI-000073-TL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:46:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9ORmeF3Jsqeo+qnRMnH2vzBXftPzCFz6N5Iuek9VOyo=; b=oE0p1QfmoplVNO4VhjX4Sr4nlL
	vXEl0vxxeUQLfR2WRePXp3O9zYUqk05oLV62mHzs5uvZXMCacF1p3lwVZppEaObqNYzmpdmwrH/Th
	BtzYU2372nig0adEAJWm5S/YOtjedsnWclU2B1janzszxUN3yTLLQXfYY4RTxQ6a1TQY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpAfI-000073-TL@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:46:56 +0000

commit 9fe89e1ea6b6d415b732fd7ae56dca90ad6fc730
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:44 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..8f04cda190 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54184.93934 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfV-0000Ot-5T; Tue, 15 Dec 2020 13:47:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54184.93934; Tue, 15 Dec 2020 13:47:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfV-0000Ol-2V; Tue, 15 Dec 2020 13:47:09 +0000
Received: by outflank-mailman (input) for mailman id 54184;
 Tue, 15 Dec 2020 13:47:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfT-0000OY-1g
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfT-0007b8-10
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfS-00008m-W4
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WJQx+23aNPVBFjbD2qHT9DfpFdJK3/1q9Mw2285X4r0=; b=G91vguAmpJabJLp5Bx03zFRcnq
	mwjA52rMr+A/OH/FQD4CjQKhHqERUJsCoIfJ31d/oq6fzDvu3QLkOfdgkqUeHG8VDZrDE5ToQALCx
	H3BKU2oRnpcOQ7tSxZKcke5r5aSaichZ8DJm9f5pd5n9fpEtZ7XXjGt5cqgzjY/PM7mY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpAfS-00008m-W4@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:06 +0000

commit d6d3b136d723001bab11b79e0bc7b318f47a110d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:29:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:49 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..65291414a3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -670,6 +670,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54185.93939 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAff-0000QD-7V; Tue, 15 Dec 2020 13:47:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54185.93939; Tue, 15 Dec 2020 13:47:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAff-0000Q5-42; Tue, 15 Dec 2020 13:47:19 +0000
Received: by outflank-mailman (input) for mailman id 54185;
 Tue, 15 Dec 2020 13:47:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfd-0000Pr-4e
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfd-0007bG-3v
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:17 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfd-0000AP-38
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:17 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=31NKW1xLQVzySpZ/Vs1SPi25kDJdRhORTpjOdcfabCY=; b=NFDrRxZIJnEDK8i7NSLJvx0pIS
	TPb8TAxZyRNOGyhQrPqb5tJ7flNFYjjg4qShLjzpvzGMoJIUkblClGMGt0xhWz26HYVwNHMIiJT/t
	LVVp7J38erHUGyxCVEuyyZsMTSeGR8I4/z9KowfuQ34k0pjzZBX7eMoc2K+qVwdHoZQw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpAfd-0000AP-38@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:17 +0000

commit 7da93258d45c1d59ac00be61bb52d4ed7d0c064a
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:29:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:54 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 65291414a3..cd15b9067c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1330,6 +1330,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1388,8 +1414,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1446,14 +1474,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1469,6 +1497,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2166,8 +2195,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2179,8 +2209,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 897ddab1e2..cd7993592c 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..28066733cf 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -276,6 +276,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -293,6 +297,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:29 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:29 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54186.93943 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfp-0000Rl-9i; Tue, 15 Dec 2020 13:47:29 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54186.93943; Tue, 15 Dec 2020 13:47:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfp-0000Rb-5p; Tue, 15 Dec 2020 13:47:29 +0000
Received: by outflank-mailman (input) for mailman id 54186;
 Tue, 15 Dec 2020 13:47:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfn-0000RQ-7u
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfn-0007bM-6j
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfn-0000Be-60
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KJ+FP4PL6Th+mrMUkCLbwX4rZacTxgyMiy0S8LlrB5I=; b=BcPLocm2neJlNNAEO3b7rFCt9S
	Ic6qILJCuH9uYCbydlWL41vRiwUXlbZhm433SBswYIAz+NVlPj76d4k6OBRpuzS2acMwxpKfuf2a7
	Y5cKIdod8vdMblithGVAkehO2SYo2o7DG6brBm4R/fv/ZzXR/tj14tgDZVtYph3AMV2c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpAfn-0000Be-60@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:27 +0000

commit d4b884bf35f46f3b5efc925847d0144c3e30dee7
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:30:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:16 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 5e2347d085..e07508a2e4 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:39 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:39 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54187.93947 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfz-0000TD-Cy; Tue, 15 Dec 2020 13:47:39 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54187.93947; Tue, 15 Dec 2020 13:47:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAfz-0000T5-9R; Tue, 15 Dec 2020 13:47:39 +0000
Received: by outflank-mailman (input) for mailman id 54187;
 Tue, 15 Dec 2020 13:47:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfx-0000St-AB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfx-0007bo-9T
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAfx-0000CM-8l
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YBRj9pGXhoOo2Wb2lK7fwT+tg/wH5bP0zbCTjFXnw48=; b=Q3uG4E6AIfVdn24zKkxK6wWBO2
	cmjmUmJ+iSLo/SH8UMaAwVB5Z8mY4Kp0HQxupaX9npXDljF7gf06zU7kN82UpqifBVbG3kWQ0qZb0
	ny8jb5wfZsOURvSShvfXfceQnzD8t2UqnrRcBxXn096qChEEWsPbSaODA0JulYFo5KFQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpAfx-0000CM-8l@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:37 +0000

commit 3c13a871cb2188958fc41f43bc5c4d28c280cfd2
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:30:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:21 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..ef32f66991 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -430,7 +430,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54188.93951 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAg8-0000UP-Dt; Tue, 15 Dec 2020 13:47:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54188.93951; Tue, 15 Dec 2020 13:47:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAg8-0000UH-B1; Tue, 15 Dec 2020 13:47:48 +0000
Received: by outflank-mailman (input) for mailman id 54188;
 Tue, 15 Dec 2020 13:47:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAg7-0000UB-Dm
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAg7-0007bw-D1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAg7-0000DJ-CB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qZ4wOK1SbZZ0oXiOIGRdsx0/fKutqOV+ZLVcMutjpXM=; b=fh/prAubB7plbA9HuAsJWo/ks2
	QH4GZFXgIGMHemkJPCslJ/4RAFvrIAVWTEbab8rbo9IEy63XcfCNUrXJM4V9m6srLSwcvyEKg7voV
	udnyYPdG8iy1v5dBMjCPUgEdNMmgb2d1G3Q9DU/EhVKWbClW0l3SRLvXuWU2Ae+FCAMc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpAg7-0000DJ-CB@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:47 +0000

commit 4943ea778876ac705b4264198663b5f8c9280fb9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:30:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:51 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d5ebfbb83a..d8053ce9bb 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -123,7 +123,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -163,11 +163,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -484,7 +479,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1784,20 +1779,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 281260d181..9578d477b3 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1055,8 +1055,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ad35266a5b..629905d218 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1830,8 +1830,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 079de1e15d..a33bd55adf 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index f3508c3c08..cab3c6ff97 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 5afa1ef6e3..a31de90508 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -318,7 +318,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 371b912887..591c598030 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:47:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:47:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54189.93955 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgI-0000Vj-Fl; Tue, 15 Dec 2020 13:47:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54189.93955; Tue, 15 Dec 2020 13:47:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgI-0000Vc-CV; Tue, 15 Dec 2020 13:47:58 +0000
Received: by outflank-mailman (input) for mailman id 54189;
 Tue, 15 Dec 2020 13:47:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgH-0000VT-GJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgH-0007cA-Ff
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgH-0000EV-Ez
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:47:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qnGXDp/IbCOl3/ZUEQQeHqExo9y/NoX43yl91TDuDyg=; b=HaqizQKci6amusZkST4fUJD9Y4
	I9wZm1ovFFZ6ULB/TgHXmrZCg7NXezYvYwUUUBOxbqxh/gEx6CvqIkA1AfG0yCLT6gseXCnHKCRO+
	v/ZNI6JpXFAYRDbNZfNI2dHZg5b+tatk/cYK+HQEipFcBm3ZxfxTB3883tqx/coHljcw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpAgH-0000EV-Ez@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:47:57 +0000

commit 51e9505a55f9f706516d959f76386df7a8877595
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:31:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:31:31 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54190.93959 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgS-0000X6-HU; Tue, 15 Dec 2020 13:48:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54190.93959; Tue, 15 Dec 2020 13:48:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgS-0000Ww-EP; Tue, 15 Dec 2020 13:48:08 +0000
Received: by outflank-mailman (input) for mailman id 54190;
 Tue, 15 Dec 2020 13:48:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgR-0000Wn-J4
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgR-0007cX-IH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgR-0000FJ-Hc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4lhyWE2TyAbwuPMXPNp/6OHE7u2a+y4ECcLaONuF7fY=; b=ZIA0FsmTyXYAnq6US2dNcVOYF8
	aZVZXnZNwH69VGc20WRE/UMZd8dTRkwcurXEQ2nJLrNoMqWWLpbcC9lW36wMq3nxvBpV652XO4rgd
	ViodtJcL/kAnfADklkjlfuLQBLGwoUtjPcSRnftTNtcif/mQqLg5LVm+35ArRnAkkt30=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpAgR-0000FJ-Hc@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:07 +0000

commit 2186c16b25402c8165d7e41ee5656bd4f94f4d6b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:31:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:31:56 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54191.93962 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgc-0000YJ-In; Tue, 15 Dec 2020 13:48:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54191.93962; Tue, 15 Dec 2020 13:48:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgc-0000YB-Fw; Tue, 15 Dec 2020 13:48:18 +0000
Received: by outflank-mailman (input) for mailman id 54191;
 Tue, 15 Dec 2020 13:48:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgb-0000Y3-M1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgb-0007ch-LM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:17 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgb-0000GB-KU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:17 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xrk+Mx2pBGTcNPVqJmtGT7IQZYLFReslj6vJzFuBoDc=; b=FhAAjgPh0WDXDe6+V3ODIc/9pZ
	keOJsHmycNJ0yLoabJ5kDiq0dLU5x8DesEAvK1+piKbz8Asn5SzKPGfGayM3AQpeuH+rA25/S/hw4
	BKTK7WnyPh65xRDpERxhyiORmAt7yM/nQ1q3xDb+qemfYZRWCNgLtKTlI9zo8HB7G1b8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpAgb-0000GB-KU@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:17 +0000

commit c8b97ff6797f594421e8ed86fc2dd09b70424457
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:33:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:33:11 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cd15b9067c..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1249,8 +1259,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1951,6 +1965,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1971,6 +1986,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1993,7 +2009,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2035,6 +2051,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 28066733cf..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -309,58 +331,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -407,15 +455,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -526,8 +580,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -670,8 +724,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -752,6 +808,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54192.93967 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgm-0000Zx-MD; Tue, 15 Dec 2020 13:48:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54192.93967; Tue, 15 Dec 2020 13:48:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgm-0000Zp-Ix; Tue, 15 Dec 2020 13:48:28 +0000
Received: by outflank-mailman (input) for mailman id 54192;
 Tue, 15 Dec 2020 13:48:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgl-0000Zi-QK
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgl-0007d6-Pd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgl-0000Go-NT
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=J4u7+V63uXLccRcX20UmcOuEkvUYaLf5fxskX4jWwSw=; b=iY3vrZAxWcEgk55gzYA4LvS8hy
	d6Q+ijqUu2H9Pa8Ev2K4rZqTcwfRG+UfJnIrOKofzOPYOCc7Hp9A88NlXVeiCcK0STJDzb7nHcKJg
	7+LCcpCEgu5yIzSoy7blpgZaKgdBwCuPthTS6r31LB0GCnfXM8/lbVsikgSG72V37XMs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.12] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpAgl-0000Go-NT@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:27 +0000

commit 2525a745e18bbf14b4f7b1b18209a0ab9166178d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:33:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:33:16 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e07508a2e4..f51979926a 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index ef32f66991..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -436,6 +443,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 8f04cda190..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,6 +341,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.12


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:39 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:39 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54194.93971 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgx-0000bP-Nc; Tue, 15 Dec 2020 13:48:39 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54194.93971; Tue, 15 Dec 2020 13:48:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAgx-0000bH-Ke; Tue, 15 Dec 2020 13:48:39 +0000
Received: by outflank-mailman (input) for mailman id 54194;
 Tue, 15 Dec 2020 13:48:38 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgw-0000bA-Ri
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:38 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgw-0007dN-Qv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:38 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAgw-0000Ku-Q1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:38 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+ftHhDj9PWf6/U1InShcfUHTI4v9LSvjMkzUTZB8C4A=; b=nGzI/qD4/Y2oSlF/RcyWnj9Xpc
	dQazzt0FsOJ9G5Rme5cnzqAEXswgeyP8ueZbEIsBhcHbyRuOsd9wxrZ+fFNFblNxkb33NVmjPClVt
	VupSjzL/8zOYoGeXHLhiwjUxc5+limf8qWVB0aqsOgCEEGuDiQFXhANG4zP6FljZ4dq8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpAgw-0000Ku-Q1@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:38 +0000

commit d2b6bf98ee27b266025e48b3c537a639a5c72609
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:35:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:35:00 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 5a8c377603..6375a1c889 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:49 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54195.93975 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAh7-0000ch-Oy; Tue, 15 Dec 2020 13:48:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54195.93975; Tue, 15 Dec 2020 13:48:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAh7-0000cZ-M6; Tue, 15 Dec 2020 13:48:49 +0000
Received: by outflank-mailman (input) for mailman id 54195;
 Tue, 15 Dec 2020 13:48:49 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAh6-0000cP-UP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:48 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAh6-0007dV-Tl
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:48 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAh6-0000LX-Sw
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:48 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=NsCeOyv23vhEfDhs1pk81FvA4FO56JAsFdFmV6ECfJc=; b=426W6Y5pat+vFSL20921ugBEq6
	tDMrWAsJE0IQh0K690c/NCeJmjdEwy1oc+QKX1gTfgkynMUj3oAlKaPr64XNCY8D6q70kTZHb0HrS
	b3rAQ74PkqmmCSJQWxW90x845yKWzE8PfqYOqJO+EhBAkH7zcumV54Wgz0Cyw0LMKRBs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpAh6-0000LX-Sw@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:48 +0000

commit 029777015c93e64830eea07e4a4c3bb23601d5c0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:02 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3d7eb91254..ee312378f7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -151,7 +151,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:48:59 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:48:59 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54196.93979 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhH-0000dw-QT; Tue, 15 Dec 2020 13:48:59 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54196.93979; Tue, 15 Dec 2020 13:48:59 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhH-0000do-Nc; Tue, 15 Dec 2020 13:48:59 +0000
Received: by outflank-mailman (input) for mailman id 54196;
 Tue, 15 Dec 2020 13:48:59 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhH-0000dg-1J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:59 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhH-0007df-0e
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:59 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhG-0000MI-Vs
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:48:58 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=covfT0UTE4nmXnrn8FhbBE2rAYnsgSqNHQmXOVKWX8U=; b=wqwuHZjxxI2tto/L7qz2uvn6xA
	jVRprCEPLsq3rwTffS6muG+rhw8etYWzeSEjuHEb/Db3IbeqbN277cxHJlqgkBYNgohGlc0DtKrdc
	joVQzlBmo/Z6o0a2LUpn3Jyx6orVaxab0gS/xbmbrgf5iAGlmZ2tLepdcJkpAlbr0es8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpAhG-0000MI-Vs@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:48:58 +0000

commit 550387fe857adcbc2e84fe4c159d84223909f6d5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:08 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:49:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:49:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54197.93983 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhR-0000fM-SX; Tue, 15 Dec 2020 13:49:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54197.93983; Tue, 15 Dec 2020 13:49:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhR-0000fE-PA; Tue, 15 Dec 2020 13:49:09 +0000
Received: by outflank-mailman (input) for mailman id 54197;
 Tue, 15 Dec 2020 13:49:09 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhR-0000f5-6M
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:09 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhR-0007dz-4c
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:09 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhR-0000Mv-2k
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:09 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6cbiZkDVy5gOaiOXELv8uMF92CiYs3E5ei0y4SbxeXA=; b=mqQc9UoaP0F2wPCrZk5vDZdInl
	lFk21siwFxHbGIbctpx+Tyw6B9KSlFyDV+/wCb3ZJEW47SJbqklDBW6cOrN/+tyHDcR8XanJ1sGHV
	fKWguEM46hg+tI782XmCC3Zk02/7Fv5SNyOSR7gQ6XADbnyNmSQrzQlfn6qrTsUwNNr8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpAhR-0000Mv-2k@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:09 +0000

commit 170445fa3c2511c7a20555be2082c7db5e1e9d97
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:12 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:49:20 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:49:20 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54198.93986 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhc-0000gj-08; Tue, 15 Dec 2020 13:49:20 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54198.93986; Tue, 15 Dec 2020 13:49:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhb-0000ga-TF; Tue, 15 Dec 2020 13:49:19 +0000
Received: by outflank-mailman (input) for mailman id 54198;
 Tue, 15 Dec 2020 13:49:19 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhb-0000gS-91
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:19 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhb-0007e7-8J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:19 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhb-0000Ni-6e
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:19 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PVsM0maNnDINdQNf1GW372BvwfK8m9tNXoBvqDSlwPw=; b=PFdR1eXhgu4ltIi2f1qiHFkVSC
	CNw4F1eTpNs/shW8UpxK3WVaDNFzM6odpAtWe4QkCjzOAL0q57rzqwqqxjTQzIsLjL7w3C04WcpDD
	44WM1/sCgR97BjSlr57J8gLMy3d9zr+l4mrCxZHpqS4viLYxNxU99dliVzzWw9UgZdh4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpAhb-0000Ni-6e@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:19 +0000

commit 88f6ff5d551b14c2e83a72196f5a95f3f27ce46a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:17 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:49:31 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:49:31 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54199.93991 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhn-0000ip-1X; Tue, 15 Dec 2020 13:49:31 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54199.93991; Tue, 15 Dec 2020 13:49:31 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhm-0000ih-Ur; Tue, 15 Dec 2020 13:49:30 +0000
Received: by outflank-mailman (input) for mailman id 54199;
 Tue, 15 Dec 2020 13:49:29 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhl-0000iK-CV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:29 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhl-0007ea-BP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:29 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhl-0000OR-Ac
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:29 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5B+npq7xiBeOv2LwrVmjYQP4n9/Vd9+ywsOzDl8LwLE=; b=BXlXOQF15EvCU+IxWpoW4CXN7k
	wCnM8lMly8sZaifAMh4jrrfQrtCWo8B65OnjODWs6b1MZxLgARbzeWmsTJGiGMP4Cjx2+RNCnK+WB
	fQP1Y9CRSPtcjoJdwQoHTghip/+QImishs/I+N3tJoiJ8AZGjWGf2etepgGT7v7wj3og=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAhl-0000OR-Ac@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:29 +0000

commit 36621b760bce6446204d82f365ee7c5c7361934b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:21 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:49:41 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:49:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54200.93994 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhx-0000k5-37; Tue, 15 Dec 2020 13:49:41 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54200.93994; Tue, 15 Dec 2020 13:49:41 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAhx-0000jz-0H; Tue, 15 Dec 2020 13:49:41 +0000
Received: by outflank-mailman (input) for mailman id 54200;
 Tue, 15 Dec 2020 13:49:39 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhv-0000jm-Gu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:39 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhv-0007eh-Ej
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:39 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAhv-0000P6-DS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:39 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=O1oee8onL2LrK+A8eZ+IpMwnljujLV7kbkDm3ass73c=; b=NzKLJf17EGuBYZ2dKG+GTZmlIg
	TpmVBd/rOf4b0hy7KJdTS+jaqbEvlAE4vxfmrhXJ6LvZTtPNQDqKSp29WwqR84Rhe3CgLgq0+hCly
	VMrm4pmIFqX9vz/A8BFtgxGDkGdjGYbVrWMC9EyEZNx+feeCEgnvmzuip9JPjHDtfDXg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: rework node removal
Message-Id: <E1kpAhv-0000P6-DS@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:39 +0000

commit 2fe5a55559a1813354a70f52a4d9548a49313cea
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:26 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:49:51 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:49:51 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54201.93999 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAi7-0000lH-5F; Tue, 15 Dec 2020 13:49:51 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54201.93999; Tue, 15 Dec 2020 13:49:51 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAi7-0000l9-1x; Tue, 15 Dec 2020 13:49:51 +0000
Received: by outflank-mailman (input) for mailman id 54201;
 Tue, 15 Dec 2020 13:49:49 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAi5-0000l0-JA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:49 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAi5-0007eu-I0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:49 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAi5-0000Q7-H0
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:49 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tWuwY0MXZUBVt6AsArxw+0D6pLswrZrvgsbJeLsru1E=; b=PQXaU1G5oWjkDGcIi2+PqQUxuw
	XhsGilYALeMkonqDMFxNvvu5JEGBPoLsQn5hWME0svSQWltLOJrVbNj6t/gv+sbo5pqUMw0wM1LCs
	nV/9uunZ5CfVqwBNhGU/0E1GgaGe7nJYH1Rx2Qwj+JcD6EFKTSaD5BczUlIJxRj4ynCM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpAi5-0000Q7-H0@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:49 +0000

commit 6be47ee3a408cf801945312a24f00f5c35e06eff
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:31 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:01 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:01 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54202.94005 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiH-0000mm-94; Tue, 15 Dec 2020 13:50:01 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54202.94005; Tue, 15 Dec 2020 13:50:01 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiH-0000me-3v; Tue, 15 Dec 2020 13:50:01 +0000
Received: by outflank-mailman (input) for mailman id 54202;
 Tue, 15 Dec 2020 13:49:59 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiF-0000mR-M1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:59 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiF-0007f1-LE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:59 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiF-0000SV-KL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:49:59 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QprmxVHjmT1AkTnhgSFs8opGnZBPNhf8JFrUiVt3qlY=; b=vI4PNL43gOvfyR4A29AdtMfXkd
	R6+M1bY1QCtDBPRMWG99owF+7SQ4/DlFFdtY96+L5wDYnMl7uTwUS94K1/KCHHlUWrFBhXqNJKhdl
	wRFyv2jOK3Yn2skQFgusxvlg2OuhoOjl2cDl1nBwxnUjbsf3cu1hQLiurOfUEk2qZeAA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpAiF-0000SV-KL@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:49:59 +0000

commit 0a6bbf99b4313e7def669d5b5e2f4e2f4d0b4720
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:36 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ee312378f7..a43bb55530 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -111,6 +111,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -122,8 +127,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54203.94007 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiR-0001UQ-AM; Tue, 15 Dec 2020 13:50:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54203.94007; Tue, 15 Dec 2020 13:50:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiR-0001UI-7L; Tue, 15 Dec 2020 13:50:11 +0000
Received: by outflank-mailman (input) for mailman id 54203;
 Tue, 15 Dec 2020 13:50:09 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiP-0001U9-PV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:09 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiP-0007fK-Op
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:09 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiP-0000TJ-Nt
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:09 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=3kItSK6O8wQh5PR8keIKjkvaka3gjw1ebYK3GszXBYw=; b=s11jhoQY5wtOl0WLXNHRHT+TPD
	QKmVBjveItsv8dObg+XtdqMFztpnFdJ6XGoTFKsoiEQCqibN+UIhMWpEnqxjJNXm2dlz4tKwBqWSC
	lMloKOv02iZ/+wh/F4XUMh9wiV/QHlTV2HWT8KzOZ2Yb1cy34P/0SHkBlvgSRjuVaSw0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpAiP-0000TJ-Nt@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:50:09 +0000

commit 1b7ed67cfafcbcba7aace46607cd36255a86606f
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:41 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a43bb55530..2092067502 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -167,6 +167,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:21 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:21 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54204.94011 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAib-0001Vy-Bx; Tue, 15 Dec 2020 13:50:21 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54204.94011; Tue, 15 Dec 2020 13:50:21 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAib-0001Vq-8s; Tue, 15 Dec 2020 13:50:21 +0000
Received: by outflank-mailman (input) for mailman id 54204;
 Tue, 15 Dec 2020 13:50:19 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiZ-0001Vh-TC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:19 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiZ-0007fS-S3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:19 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiZ-0000U0-R9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:19 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/V0F+6ZfkCmYl+s6tI/ZTm1z5GRvaewW78+TBFDnHUA=; b=eNhHlFMQ+LXU7phwIjVBbPiT/j
	Gk/GqKnGTP9QSuAfHcg7plai5R6gLg3tvER21e6FN1sVER3kOIxe+BeVk9YNzBv6Qcpsm8Vy1CrAc
	FbkNjtC6AKMRUtKQmCyTO5a/xV+3jo+Z3Oh66lbXPvZ6YOYM7zh0i1DtIXtZrUhgdPh8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpAiZ-0000U0-R9@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:50:19 +0000

commit 57261ac3434c304f5c96cbb2da5cce8493a7662a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:46 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2092067502..e4966c89e3 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -154,15 +154,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -173,6 +175,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:31 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:31 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54205.94014 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAil-0001XT-DJ; Tue, 15 Dec 2020 13:50:31 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54205.94014; Tue, 15 Dec 2020 13:50:31 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAil-0001XL-AQ; Tue, 15 Dec 2020 13:50:31 +0000
Received: by outflank-mailman (input) for mailman id 54205;
 Tue, 15 Dec 2020 13:50:30 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAik-0001XB-01
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:30 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAij-0007fq-VW
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:29 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAij-0000Ut-UC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:29 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=51wiMSgbfeDlyiunI5vD6Qe/x21xv11DfyrHlbHoE1w=; b=21gXdF45Ru51BMCG26b7pbJYLX
	nfV0bPWdsDDZjrvAf1rRSoHkoDJWoyqPs9WFsjKPqMzfF6uUV+KLFs80fNwhX4Z0MYizLtoeDnLS6
	Guzp/F4DV19J/y2Tu4OW2+/5T2VF46cqC8fL9pEpkneFXkyxeAaITzDAn80mR8P4dEHo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpAij-0000Ut-UC@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:50:29 +0000

commit 966f266be0806f3fa95b4c42e8e60fc2ee9f1da8
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:36:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:52 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 74c69f869c..0a0e43d1f0 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:41 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54206.94018 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiv-0001Yy-F4; Tue, 15 Dec 2020 13:50:41 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54206.94018; Tue, 15 Dec 2020 13:50:41 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAiv-0001Yq-Bu; Tue, 15 Dec 2020 13:50:41 +0000
Received: by outflank-mailman (input) for mailman id 54206;
 Tue, 15 Dec 2020 13:50:40 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiu-0001YY-3C
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:40 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiu-0007g3-2U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:40 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAiu-0000Vg-1H
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:40 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4TBXuiV7Eunn/Y56jaUV7JODhdPAi3VzpPrlJT/TlJw=; b=3DOn6X/R7B3TBKqL5IRqjAGq98
	NpjrOqZnuR84h45FkvvX8xaBJkD9fqFmWhIIU9d6wD/TMlwbvrFGN7ICVODxe0+t5ba4avdNmwxBW
	qPhH0Cp9ztu5A2pQ3rAxpv63drDrcTgVYZYrlnsErJz2NSW3+TI8J5K6qMUDO8YpKj/o=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAiu-0000Vg-1H@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:50:40 +0000

commit b3f80a38b907e27cf9af6aae10f96594074ba363
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:36:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:56 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 0a0e43d1f0..f374abe998 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t domains cons data =
 let do_error con t domains cons data =
 	raise Define.Unknown_operation
 
-let do_isintroduced con t domains cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:50:51 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:50:51 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54207.94023 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAj5-0001aR-Hn; Tue, 15 Dec 2020 13:50:51 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54207.94023; Tue, 15 Dec 2020 13:50:51 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAj5-0001aJ-Ev; Tue, 15 Dec 2020 13:50:51 +0000
Received: by outflank-mailman (input) for mailman id 54207;
 Tue, 15 Dec 2020 13:50:50 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAj4-0001a9-66
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:50 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAj4-0007gB-5L
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:50 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAj4-0000WF-4U
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:50:50 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=x2otSDYTpJPEw1Q3VoriOFWy044t+MPbvYjlAFBRhwo=; b=4be2VEDTH8PqbtsmG5hcDH7smm
	eB/7hnDbReahu+kLzO1/W/mCapPoawJ3BhEI/1YP6sgB0lwuonA7ocyirMtWMebbwu4kX20uc64Ok
	CybkVRl+Gme4DgtGLwwMcW/0pF6J0nyEqxAGiUJTw6s3SOsvVci2NW/C1ncn1m8Sxl5E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpAj4-0000WF-4U@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:50:50 +0000

commit 771a105b2880e6b40098d7a303400b3525a95df1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:00 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index be9c62f27f..d7432c6597 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:01 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:01 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54208.94027 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjF-0001bx-JS; Tue, 15 Dec 2020 13:51:01 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54208.94027; Tue, 15 Dec 2020 13:51:01 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjF-0001bp-GN; Tue, 15 Dec 2020 13:51:01 +0000
Received: by outflank-mailman (input) for mailman id 54208;
 Tue, 15 Dec 2020 13:51:00 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjE-0001bf-9K
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:00 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjE-0007gM-8C
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:00 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjE-0000Ww-7O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:00 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=CftFd2QeZjpXEhn5qGtZMtJGAdiFR0JDD6an56qPYRE=; b=36SgxE/1hR3NwlNnkg1a7vwsuc
	QHghP/8/f3Cndf8t83OXmZs5+QP4609W0JmQ3ZG5d4t9lYj6GizKxB8CJjGIuDfF6SAymnZvRMqa7
	crRbp61I7CsDjcAfDptrXgt29gzsDMpCLs+0zFmY2tagKbOKtTcdaPkCCDYHt5pmRPPM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpAjE-0000Ww-7O@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:00 +0000

commit 495e97365a88a09c3479812c6428a5ec8a1418fd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:05 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:05 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f374abe998..c3c8ea2f4b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6375a1c889..98d368d52f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 49fc18bf19..32c3b1c0f1 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54209.94031 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjP-0001dD-L9; Tue, 15 Dec 2020 13:51:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54209.94031; Tue, 15 Dec 2020 13:51:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjP-0001d5-Hx; Tue, 15 Dec 2020 13:51:11 +0000
Received: by outflank-mailman (input) for mailman id 54209;
 Tue, 15 Dec 2020 13:51:10 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjO-0001cv-CM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:10 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjO-0007iE-B7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:10 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjO-0000YQ-AH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:10 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gk4NNm0xPL51BRJMHSnFzNFkFEd8/kBs0NmqKB2TFtQ=; b=e+Dy7qvuQh1b3R1PCZOb7XoMjr
	mk0UAmDaSVndsvDZEqml2xa2XWjfHfewOoN5jyo3T6/knfG+ULIGDC0Xbf51oGn6Ve2VeivM8BlQx
	Mt10qikQVVFbIoIFn/M00aqnz65ctw5znJsevvPvRb+7a9fKr0j/dMrVtN+YhkyX78Lc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpAjO-0000YQ-AH@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:10 +0000

commit 57244315c445aca68672b15c7a74a8152634668f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:10 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 ++++++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 ++++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++++-----
 tools/ocaml/xenstored/process.ml     | 36 ++++++++++++++++++++++--------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 84 insertions(+), 28 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index d7432c6597..1389d971c2 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index ae7692819d..020b875dcd 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec x = function
 		| None         -> ()
 		| Some watches -> 
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index ea6033195d..99c7bc5e13 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index c3c8ea2f4b..3cd0097db9 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			Connection.end_transaction c tid None
 		)
 
-let do_watch con t domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) = 
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con t domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -414,7 +419,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +438,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 23e7ccff1b..9e9e28db9b 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 32c3b1c0f1..e9f471846f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:21 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:21 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54210.94034 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjZ-0001eT-Mw; Tue, 15 Dec 2020 13:51:21 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54210.94034; Tue, 15 Dec 2020 13:51:21 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjZ-0001eL-JV; Tue, 15 Dec 2020 13:51:21 +0000
Received: by outflank-mailman (input) for mailman id 54210;
 Tue, 15 Dec 2020 13:51:20 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjY-0001eC-Fs
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:20 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjY-0007iN-FF
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:20 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjY-0000ZI-Dq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:20 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=smO0KFVbqh0OqNuaD88/ldLWTixYJUMXstfUENBw2yY=; b=JP7u7/2+2RNMh7AgGww9s/chYm
	ZeiFUIAkTRfKncZ/CNRdrbPFoiOFPQc0jRJHkSbo8CIYNe1jfOGk/SJzQqNN3WuX7BsgMODSDmtvi
	rya7xreUadiGtRQaaP3FY8mVL0LiiQe15d2WKWbk8Iid2zZgQQbE5YL+suv+xwG0KSaU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpAjY-0000ZI-Dq@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:20 +0000

commit 7791d2ed24daa1cc108139790e6fc0bcc927794f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:15 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:15 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 1389d971c2..698f721345 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 6579b84448..d5d4f00de8 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index e9f471846f..30fc874327 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:31 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:31 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54211.94039 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjj-0001gH-Pq; Tue, 15 Dec 2020 13:51:31 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54211.94039; Tue, 15 Dec 2020 13:51:31 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAjj-0001g9-MU; Tue, 15 Dec 2020 13:51:31 +0000
Received: by outflank-mailman (input) for mailman id 54211;
 Tue, 15 Dec 2020 13:51:30 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAji-0001g1-KJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:30 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAji-0007io-JX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:30 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAji-0000a0-Hk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:30 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/RctW6r8M3gul0nhB4yFF8e/sUytAygkrJh9pCfa2MA=; b=bSiTZs7XraknGjALhHKhTujs7J
	MER3hSxDT2Pghctzup6YTr1UdvrPCf1i3IuqK/EDwtuL02VgfhOxTppuvKK36CpJN2s84iV8y4EyW
	RYo8U2G6oP5sSQ430mxV2HNIG6drm6VnlWuLuEN0ZvR2EC6V2mX3GssCAkZKFGyEPP2s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpAji-0000a0-Hk@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:30 +0000

commit 1034a45d2da1b9ff5b02235b3bf8458b238b9e98
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:37:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:43 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..4fbe5c759c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..f5e7af46e8 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -301,58 +323,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -399,15 +447,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -518,8 +572,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -662,8 +716,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -744,6 +800,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:42 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:42 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54212.94043 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAju-0001hZ-RI; Tue, 15 Dec 2020 13:51:42 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54212.94043; Tue, 15 Dec 2020 13:51:42 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAju-0001hR-O6; Tue, 15 Dec 2020 13:51:42 +0000
Received: by outflank-mailman (input) for mailman id 54212;
 Tue, 15 Dec 2020 13:51:40 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjs-0001hG-NJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:40 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjs-0007iw-Mb
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:40 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAjs-0000aw-Lm
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:40 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oB9TL6eRpY6C8MQHDh+67B728jU7GR1yuKYUy9unlTU=; b=K8AyRlyAFqvwWNJW3hLSwvxIuH
	5VO8zIU7NdWtvE5wJbAbsAUmDs0XtPTF8DS2IpIgVkouAVpMcoNQ0kgO8NlWihAQtoU4TdU+J7KX6
	QPmDbM4zm0r4w5cDH95fUf7sxS2/FdP+Cpu2hqQovarMapHdOqq3klh8LzGsXCX68T38=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpAjs-0000aw-Lm@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:40 +0000

commit e36f81fc8efe841f90a3aa69f809ea3ae95888a5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:48 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 3cd0097db9..6a998f8764 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches 
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 98d368d52f..6bbbd05552 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 30fc874327..183dd2754b 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:51:52 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:51:52 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54213.94047 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAk4-0001is-TG; Tue, 15 Dec 2020 13:51:52 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54213.94047; Tue, 15 Dec 2020 13:51:52 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAk4-0001ik-Pq; Tue, 15 Dec 2020 13:51:52 +0000
Received: by outflank-mailman (input) for mailman id 54213;
 Tue, 15 Dec 2020 13:51:50 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAk2-0001iX-Q7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:50 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAk2-0007j4-PS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:50 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAk2-0000be-Og
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:51:50 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PS4OrGI9wFwoQxsgsza99SINXjJagkoLy+izR0uNcGM=; b=HDJQUyhkZM7LlO1Kwf7/8H2leG
	GW59QiNwXXTY1LJtfrJbxdq9drCHvyOJw4oDbbVkLmduyqa0Z/qYiu+R4IpeL2D2rcUC43jVfNP7t
	wnLuGoIYNUKAHH+HSzwZrt425Zv+Vuej4oOgnfeWAVFtsPMA087PhTidXJ1qXP753XwI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpAk2-0000be-Og@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:51:50 +0000

commit b3f4121ba2be9f995d3416719c0eb367a4d10fa3
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:04 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index d5d4f00de8..bef633090b 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 183dd2754b..70f1bf8d2e 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54214.94050 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkE-0001lu-W0; Tue, 15 Dec 2020 13:52:02 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54214.94050; Tue, 15 Dec 2020 13:52:02 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkE-0001lk-T2; Tue, 15 Dec 2020 13:52:02 +0000
Received: by outflank-mailman (input) for mailman id 54214;
 Tue, 15 Dec 2020 13:52:00 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkC-0001lY-T2
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:00 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkC-0007jE-SH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:00 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkC-0000cR-RX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:00 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gTHo8gm98JqjD+3cILl1Es/zFRTdwHlOQ70QJas7SnI=; b=0aNzGIM1fw8e4S4zpYt17Mdhg2
	47rONc5onXGMY6AQF7FAvae5vN+ZiUCeQ/GKm+rERTtSWdUeInFkpnOg0ar/pBjWY06M9ZMdWLGU2
	8qUXjAsowK8Q8daOXOrGhE9wQfiUlslDoVjKNlPfKW5MO/9H+llWJHvM36DaZGNKf9T8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpAkC-0000cR-RX@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:00 +0000

commit 40537713d604ef8065e09fa3eb606b3782b0d3f0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:38:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:09 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 4fbe5c759c..e8f2057a32 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54215.94055 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkO-0001n8-1l; Tue, 15 Dec 2020 13:52:12 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54215.94055; Tue, 15 Dec 2020 13:52:12 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkN-0001mx-Ul; Tue, 15 Dec 2020 13:52:11 +0000
Received: by outflank-mailman (input) for mailman id 54215;
 Tue, 15 Dec 2020 13:52:11 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkM-0001mr-Vt
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:10 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkM-0007ja-VD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:10 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkM-0000d8-UV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:10 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kpqE0m1vX1Vzhhs+LtQEQXtpmpGlK+j/1h0VqIv0oGA=; b=F7phTl1lp7vXfmAL33dKLXCfQa
	/twCexkRxvN5hpSMFnJiCz1+KjMDlhVJwK4Mq95SMZXgXyQh1GAo58R1Xv60yGAKt9P/80S1Bubek
	I/9eFcF8gZo0bxnBvUuZXJULQkmbjLUsrKXH23lWMNvIej+rXmwPNC3B346PNqwz7jAM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpAkM-0000d8-UV@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:10 +0000

commit 4cc23870318f01c1fbd33159b3351c8128df49a1
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:38:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:14 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index e8f2057a32..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index e4966c89e3..6d1d0460b4 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -82,6 +82,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index f5e7af46e8..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -298,6 +298,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -315,6 +319,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:22 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:22 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54216.94059 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkY-0001oN-3B; Tue, 15 Dec 2020 13:52:22 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54216.94059; Tue, 15 Dec 2020 13:52:22 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAkY-0001oF-0F; Tue, 15 Dec 2020 13:52:22 +0000
Received: by outflank-mailman (input) for mailman id 54216;
 Tue, 15 Dec 2020 13:52:21 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkX-0001o7-2N
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:21 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkX-0007ji-1i
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:21 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkX-0000dr-0x
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:21 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sAYNnFd6IHwHMjzUoIxUKhbCM54y6V0qf2hTbUfOlxc=; b=RsEayIz+h2DHxqUYVQLqgfN7vA
	Zr8LIDa7HQ4e3utwTzog1l7uSS5y5BWyR6g/ZBqLuDIjH5ZmuV9/DdsSUh4+5+v1WTsiFLRsApM1m
	fIKQ5CCRigv31DLW5JGdvJQ7qTRBNUEUPMOkaB4tVIHrrNBLV2KXXMPUy2ym61IZw7To=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpAkX-0000dr-0x@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:21 +0000

commit 1e870589fac5717761a44d9da52e95decd45c4ae
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:42 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 020b875dcd..4e69de1d42 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 6a998f8764..12ad66fce6 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con t domains cons data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:32 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:32 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54217.94063 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAki-0001q0-4s; Tue, 15 Dec 2020 13:52:32 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54217.94063; Tue, 15 Dec 2020 13:52:32 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAki-0001ps-1m; Tue, 15 Dec 2020 13:52:32 +0000
Received: by outflank-mailman (input) for mailman id 54217;
 Tue, 15 Dec 2020 13:52:31 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkh-0001pj-69
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:31 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkh-0007k5-5W
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:31 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkh-0000eT-3o
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:31 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tFIIp4YqFGKs1U4ZI3JrRhnAErMyVum98hyUjr60dps=; b=ol2oRCmHCytjkNEiAinMLRxrbl
	hADYR3+rzhQz26MquJPXL2Meb/jLRfBy39xVhQkAl97aRiUsm01Tkdml8XB9f3j3SCT8UFZ1dr2yi
	PxAWtBZSZ4iPxddyvl9MkrMoqlD+EbI1SKnsuEqcKeAoyNP8CaVRIxaZjTDI1UQx/rhc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpAkh-0000eT-3o@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:31 +0000

commit f1f3dee7477a8f4e5b17a0025bbb77f0f3a9e3dd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:47 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6bbbd05552..2a694562bb 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:42 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:42 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54218.94067 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAks-0001rL-6Y; Tue, 15 Dec 2020 13:52:42 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54218.94067; Tue, 15 Dec 2020 13:52:42 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAks-0001rD-3O; Tue, 15 Dec 2020 13:52:42 +0000
Received: by outflank-mailman (input) for mailman id 54218;
 Tue, 15 Dec 2020 13:52:41 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkr-0001r4-As
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:41 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkr-0007kC-96
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:41 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAkr-0000ez-7s
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:41 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=quvYAKFS4e9ZvNR6/ONo6tie6nxbmdBu+vzww0h7Pfg=; b=ViaPYDhXmNGXBgW89cDXtmIfqK
	dBbPAtL9czrCIJX3PAk0jqWFFp6W7AOibKRQe0Xux4JIg4Nfw/VFGtUrn7mKncUEhDRpa2XxQmg/h
	wx3bkUgUYt4Qd94kCGAZN5IuQFPyew3jsPM1VSCSCA2ZyNkFv+KJYrTJkO7iVdFA6YVM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpAkr-0000ez-7s@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:41 +0000

commit 24f7d0305aed5a9657202bb8b4927dfbebca82a2
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:39:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:39:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 35857dbe86..5182ca388f 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -121,7 +121,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -161,11 +161,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -456,7 +451,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1764,20 +1759,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 2f8aed8cb9..8adc39cc92 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1111,8 +1111,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(hvm_msr_tsc_aux(v));
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 332f2d810d..e2019aae7c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1782,8 +1782,9 @@ void vmx_vmentry_failure(void)
     domain_crash_synchronous();
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index c6461cdcd5..5d373c371f 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index f3508c3c08..cab3c6ff97 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 360c38bd83..045a563756 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -328,7 +328,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
     /* nestedhvm: translate l2 guest physical to host physical */
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 20eb7f6082..36663bb307 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:52:52 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:52:52 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54219.94071 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAl2-0001sh-9Y; Tue, 15 Dec 2020 13:52:52 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54219.94071; Tue, 15 Dec 2020 13:52:52 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAl2-0001sZ-6b; Tue, 15 Dec 2020 13:52:52 +0000
Received: by outflank-mailman (input) for mailman id 54219;
 Tue, 15 Dec 2020 13:52:51 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAl1-0001sS-EI
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:51 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAl1-0007kK-Cn
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:51 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAl1-0000fZ-BA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:52:51 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FVP7/saD6wmhvU/tDWN+afiM7VEoj1PexyoE1SAtVOw=; b=dAJ4N8TLgVxNh3Jk9wAOYeoYa8
	lYQb40Nh/3Z80vYPAmjOQfHYI3ZRjZ+5FK5vVBSrU9GvFn1c9G9JWspFRMjJ3KIT2HAM/txQIlmok
	7D2jPo4rVDzy5Ci7z7XzLdhr9DRp3p7HmTuZk4Ru1tgyQtraln3Gp4jdMvydnGfSWnRo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpAl1-0000fZ-BA@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:52:51 +0000

commit 2d4982550da86ecd50a4c4b0b558bd2a3911514b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:40:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:40:12 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 0a90a8404d..ab9e496696 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -227,6 +227,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -452,6 +456,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -462,10 +467,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:02 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:02 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54220.94075 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlC-0001tz-B4; Tue, 15 Dec 2020 13:53:02 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54220.94075; Tue, 15 Dec 2020 13:53:02 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlC-0001tr-8D; Tue, 15 Dec 2020 13:53:02 +0000
Received: by outflank-mailman (input) for mailman id 54220;
 Tue, 15 Dec 2020 13:53:01 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlB-0001th-GH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:01 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlB-0007kV-FU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:01 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlB-0000gJ-Eh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:01 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5N9RZi/aIjEl00rIoMHkmDetTHnPckh0ckAIGK48b0c=; b=KtwcWBKRGGeO6L018T3o1o9icS
	XT7hesogtZX0fCsd6cjSnYvGj/pUKwwInd3fpN+BnHPcFJkbYAcZLsBeW26IGhSKfMla9xoh4fXMM
	3kxA6XPIr1zWNUJkGfA9CI6FnvvASvH0oeXJFeOg8BjU84UabxzZVM1wxZh/CODsLvYo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.11] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpAlB-0000gJ-Eh@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:01 +0000

commit 310ab79875cb705cc2c7daddff412b5a4899f8c9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:40:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:40:35 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index ab9e496696..454ca40743 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -590,6 +597,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54221.94079 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlN-0001vN-Cz; Tue, 15 Dec 2020 13:53:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54221.94079; Tue, 15 Dec 2020 13:53:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlN-0001vD-9k; Tue, 15 Dec 2020 13:53:13 +0000
Received: by outflank-mailman (input) for mailman id 54221;
 Tue, 15 Dec 2020 13:53:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlM-0001v5-Hh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlM-0007kn-Gw
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlM-0000kD-G6
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=q50aDzbspk63c88PJurIxqx1M+pIGr4M2ntWbnv+xhk=; b=ipviTLtcr/RlmSg42aW3a5Blgk
	hJIJ+iixWb8nP4Y1yUzlmErIJPNA+0ulJFfQliep9c10ImbHuUjaU1qEezQPU/GK+PKUgFy2epz7J
	KW3KawFmM+/7vWGkLyhHtdypbNXhQLiGD+SpY1iXj/p+B98MT+y2g+LV9a88frBmsZ58=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpAlM-0000kD-G6@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:12 +0000

commit e8231b61b22b8836f40b2f86394b52242b36c4c4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:42:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:32 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 5a8c377603..6375a1c889 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54222.94083 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlX-0001wa-EV; Tue, 15 Dec 2020 13:53:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54222.94083; Tue, 15 Dec 2020 13:53:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlX-0001wS-BV; Tue, 15 Dec 2020 13:53:23 +0000
Received: by outflank-mailman (input) for mailman id 54222;
 Tue, 15 Dec 2020 13:53:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlW-0001wI-LM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlW-0007ky-Jn
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlW-0000l5-J2
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=x9Trb3DgJX4XbC4LKi+d48JABPig5fFnQtZVDMF6xO8=; b=Nefga+lyVCUyoBj3YvC9qV14ML
	iHF+aLytd8QpKfkM7FiFJ2bNhu8zGRxoJCaWOqPsjMYgVCFJntyRwYj6jCYB5+niYpaNgOwfeVWlb
	YL6pDxa1SVC7Gi0eOnhSD6MS2Zq83f1HWo0b4dm1mRV1cg21ASIN3e0scEluqv55QE80=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpAlW-0000l5-J2@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:22 +0000

commit 3afd3844aa0af868357c9ab2152b76d0ba261477
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:46 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3d7eb91254..ee312378f7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -151,7 +151,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54223.94087 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlh-0001y7-Fy; Tue, 15 Dec 2020 13:53:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54223.94087; Tue, 15 Dec 2020 13:53:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlh-0001xz-D5; Tue, 15 Dec 2020 13:53:33 +0000
Received: by outflank-mailman (input) for mailman id 54223;
 Tue, 15 Dec 2020 13:53:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlg-0001xs-Nf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlg-0007lP-Mx
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlg-0000li-Lz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4VawDPNtTiGK4l8vqhmMaDxXf6CXmYeuoRHPx8uMVZM=; b=B0zWUsLn5+SwSQgwnFDDL2cLoM
	fRFtVfr60ZKHohoDkkLf7+qEGrFiE/UBsOMcMo2KUOUCJ8KGfrmDevJjH10xHX2WgyW9yLyx6nrbJ
	E/msjjCmUg+JdNS8tJwbiR0F7MVgt3yB5rfq+3CHDHqx7stMbiks3U+cdUIHv73w6aHI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpAlg-0000li-Lz@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:32 +0000

commit a043a64bd9415042e680a10ac75c34dc4fe08240
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:52 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54224.94090 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlr-0001zP-Ha; Tue, 15 Dec 2020 13:53:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54224.94090; Tue, 15 Dec 2020 13:53:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAlr-0001zH-EZ; Tue, 15 Dec 2020 13:53:43 +0000
Received: by outflank-mailman (input) for mailman id 54224;
 Tue, 15 Dec 2020 13:53:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlq-0001zA-Qc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlq-0007le-Ps
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAlq-0000mG-P1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=IJKTYsh/zWbeRyg2i8XEdRAdjJzj1WcjdxTkrlljwQc=; b=sfLtLN/mLZfO1UMQXfVkEJKHQ/
	TU5YKJzH5FeF2oP9UriN4tv5B2ey+v9l4kleVUtH+U+BJ9ZzfRR9pgp76ql3d9xl2YSrZWG0MHy4R
	KL9xW9R80jUO1dXuozy6EmvpapVo91n0dTM5VgXC+TIh1lB8kCP5kE988urqraXaQn+A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpAlq-0000mG-P1@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:42 +0000

commit 77d6b2b600dfcfe274ec6a553c3fa700c8b6cac5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:03 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:53:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:53:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54225.94095 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAm1-00020n-KR; Tue, 15 Dec 2020 13:53:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54225.94095; Tue, 15 Dec 2020 13:53:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAm1-00020f-HV; Tue, 15 Dec 2020 13:53:53 +0000
Received: by outflank-mailman (input) for mailman id 54225;
 Tue, 15 Dec 2020 13:53:52 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAm0-00020Y-Tc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAm0-0007lm-SX
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAm0-0000mr-Rk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:53:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DYgHT6ua8VrhlPhw3tztF/bmmLcpwJlVv1D3GoyjKVI=; b=tPwiIGiSPdxzQ5EnzZmmTTY0RQ
	gCOo97Fey1RD88H+mJn3gqozLGeBKg+55xBx8qlU9dZGVQafF0YcS93re+RHJCkR9skhfMYIXyJFp
	XWr+rqFXWheek7vP9tBy/a6ZpXtXnx4iANaXHmdJpL2nIOFL+eNdWcUzlRMOlSSzk/mQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpAm0-0000mr-Rk@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:53:52 +0000

commit 06092d1f96354d75f91d2acd04c0c1232f2b9eec
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:07 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54226.94098 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmC-00022G-MO; Tue, 15 Dec 2020 13:54:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54226.94098; Tue, 15 Dec 2020 13:54:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmC-000227-J5; Tue, 15 Dec 2020 13:54:04 +0000
Received: by outflank-mailman (input) for mailman id 54226;
 Tue, 15 Dec 2020 13:54:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmB-00021w-0n
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmA-0007m7-VV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmA-0000nc-Uf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=I1kas3QEi9AXa7eUgUTZkC4tnCqGrpHrqsijGWMPCdc=; b=7NGzl4qzzUl95VJz8UwG5RwKd4
	ZgPwC7rXYQJxF4zShKguLL9sd28dFW7gvkpziP+9Ynj727UazDzinf8EMoDwP98a4Qe3PeTDUKbks
	d3qU8aX4a77+bQUZH19rBpxvTigR/DxZ2zx/KIxO0Iy8KJNC8IGtYnym/lZwyeOQday8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAmA-0000nc-Uf@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:02 +0000

commit 2fee46c8d74e16647b7b1f63cac42efa26a77dbd
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:12 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54227.94103 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmM-00023P-Nz; Tue, 15 Dec 2020 13:54:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54227.94103; Tue, 15 Dec 2020 13:54:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmM-00023G-Kf; Tue, 15 Dec 2020 13:54:14 +0000
Received: by outflank-mailman (input) for mailman id 54227;
 Tue, 15 Dec 2020 13:54:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmL-000236-48
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmL-0007mH-2J
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmL-0000oV-1R
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HWiEmXtU4vaY4JS+zgIoJRa0re3pU/4hp1yo2sQ45vc=; b=xN9c4aqjD97zB0I8lQvX8AdGjb
	Y7I7WyRG2TA1dmdjpu1/JlPGoXKJuBGcTGmTM86f4GnR2wVMzqcsV6UEOdYuyIFjikdYP3RJyV8ex
	Wwdnx6YSnDSGvQKBXAzN8iSpyxgrlJKc/UNpM5rzGJ7ks323LyIg1/N0HxpSJA5plRYU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: rework node removal
Message-Id: <E1kpAmL-0000oV-1R@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:13 +0000

commit 8cb4d2d2d60f367b0f1722ba3d5de98b93c33ee7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:18 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54228.94107 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmW-00024a-PJ; Tue, 15 Dec 2020 13:54:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54228.94107; Tue, 15 Dec 2020 13:54:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmW-00024S-MG; Tue, 15 Dec 2020 13:54:24 +0000
Received: by outflank-mailman (input) for mailman id 54228;
 Tue, 15 Dec 2020 13:54:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmV-00024G-6g
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmV-0007mP-5B
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmV-0000pX-4P
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=RL3tCN00rRbTd5enItPb5LwPHZZ++PxFZ0202gFGI7w=; b=TM4/vF5DrohbGG1na4pLUhBzdc
	v3a2VB/fjVcWeVAhqDxyfkwTiFQX3ysd4xF/mrisH1IR1stRvyAq3SSVg9hMkmt8W4iIRH++gD7Bd
	NCjJzBsyz3JOc6QUvS4IY/1I9+A/YFllxmApXT7yxZmI7tCYpvM3esCcYRR6dqSqHrFo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpAmV-0000pX-4P@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:23 +0000

commit 9edd614ef8dcd6339a8ccd6c1e38c224c5711f1c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:22 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54229.94111 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmg-00026G-R0; Tue, 15 Dec 2020 13:54:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54229.94111; Tue, 15 Dec 2020 13:54:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmg-000268-Ny; Tue, 15 Dec 2020 13:54:34 +0000
Received: by outflank-mailman (input) for mailman id 54229;
 Tue, 15 Dec 2020 13:54:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmf-00025y-Aa
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmf-0007mq-8Q
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmf-0000qC-7P
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nkoW3PfQ71e8nr9FkMDwfYnu9Hi1YYCkq2yISFkOvGE=; b=tvwp0e72JthnYtv8tUoD951F/Q
	MLxs/mL3VSMni6ysovcMpux9GUAZCeoqlMmkFxe8MxSzEsmPG7uzaidYne70BlIZacfsLH21xKC8h
	+zbUTXfgLbjUtl6yZ1PJ6aYWo4eipacTfmEZY0vy7V+I+lek6Zrlifnz2GWTBKUPHZV8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpAmf-0000qC-7P@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:33 +0000

commit 36580444463dbac63de5b6b4218910df5492eef9
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:28 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ee312378f7..a43bb55530 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -111,6 +111,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -122,8 +127,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54230.94115 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmq-00027e-U6; Tue, 15 Dec 2020 13:54:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54230.94115; Tue, 15 Dec 2020 13:54:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAmq-00027W-RB; Tue, 15 Dec 2020 13:54:44 +0000
Received: by outflank-mailman (input) for mailman id 54230;
 Tue, 15 Dec 2020 13:54:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmp-00027K-Dg
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmp-0007n4-BR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmp-0000r1-Ab
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=lVNETWe3Y8kQTcXVk0Ex2bExCHOefyDwAqMXK141zT4=; b=JVpWok7VDJZpDDv/6FN7xE5ADi
	9rGujuUpkcbXRm00FjIsTRb6Ra7UQG1c/tMbghJk1YScKVE86x9eZQJbjbh3JfmBSqPVwkHO3Af4p
	Zhpi1vmbjKoxtFKW8WndUMgYttSvfA5WXYAM9Pih9I6m3/7ffNUnDJKcoB86MqEMQfAE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpAmp-0000r1-Ab@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:43 +0000

commit f06e4ac53f409216b53b0d8824ab44fadeb6cf55
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:33 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a43bb55530..2092067502 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -167,6 +167,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:54:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:54:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54231.94119 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAn0-00028u-Vr; Tue, 15 Dec 2020 13:54:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54231.94119; Tue, 15 Dec 2020 13:54:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAn0-00028m-Sj; Tue, 15 Dec 2020 13:54:54 +0000
Received: by outflank-mailman (input) for mailman id 54231;
 Tue, 15 Dec 2020 13:54:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmz-00028b-FB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmz-0007nC-EV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAmz-0000rx-Df
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:54:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=phnhRdY/9yVVWYg9YjT0ffC3WgkWqeKo+U99dBDZD4U=; b=RJK5gD/SD9Rj+nzt1taRQ65nnt
	PIpnPmI7ytiZvhvc/0UDs6/TZ4qP4sATVk8IbHkkl40WgZf2if+P/fnKR3nh5en3BdR3zUdJ9KPKx
	dzxDDvzTrTENoyZ1bXuXHsk4IB/td4CSrrAXeHksTQLLkexk0oywGlwLwm8iFdtN2KNU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpAmz-0000rx-Df@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:54:53 +0000

commit 03937f9928452325400bde39212f74a2a9fe0a88
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:38 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2092067502..e4966c89e3 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -154,15 +154,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -173,6 +175,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54232.94123 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnB-0002AL-1L; Tue, 15 Dec 2020 13:55:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54232.94123; Tue, 15 Dec 2020 13:55:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnA-0002AD-UV; Tue, 15 Dec 2020 13:55:04 +0000
Received: by outflank-mailman (input) for mailman id 54232;
 Tue, 15 Dec 2020 13:55:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAn9-0002A2-I8
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAn9-0007nY-HR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAn9-0000uS-Gh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6RFSpIGpdV1u1z0y57Ka2hZ9bYI9vVElKFOat36BHLo=; b=NO/33a33gHaO3P/JWDc7rsHtOx
	7NnZh9NTTyck09eZKCEhwC++mKVGtiIuY4+DKQGND3akKTUYraJKjP4QTJVffutXnQjG9CPaw2IQe
	kxATTwzr7a4MaR4v+bgyeRoM6PRlfgCvfdF9+OVEUKQk64bLUPY/KJ9ij29CAKAtJJZE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpAn9-0000uS-Gh@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:03 +0000

commit 57a55a429bb58a39c470a25826e65e1fc4ebf50c
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:43 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 74c69f869c..0a0e43d1f0 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54233.94127 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnL-0002Bf-2p; Tue, 15 Dec 2020 13:55:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54233.94127; Tue, 15 Dec 2020 13:55:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnK-0002BX-W5; Tue, 15 Dec 2020 13:55:14 +0000
Received: by outflank-mailman (input) for mailman id 54233;
 Tue, 15 Dec 2020 13:55:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnJ-0002BM-LC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnJ-0007nf-KN
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnJ-0000vI-JZ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wF6YKF1CLqL6eGBE0Nr+rZK+0IPm9d54WT+cH1mJLHs=; b=MmMd68SDVmtoDv+CaF6mH6x+t+
	jvGS/y7K76GL+WNKVIrs1/2XVOChPpcojrG6X+sxDYhjIvaFfL514pUUPx1lGGgmW3KKxMt4d0vXf
	z7LT9peatfQarfc+Dry+3fkmthqKi86ATEllsBN5qp4raKtBQs8UW18sesAGqut/GAVA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpAnJ-0000vI-JZ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:13 +0000

commit 59dc712c72076fb778659aaba40da5d623fe8ee1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:49 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 0a0e43d1f0..f374abe998 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t domains cons data =
 let do_error con t domains cons data =
 	raise Define.Unknown_operation
 
-let do_isintroduced con t domains cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54234.94131 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnV-0002DX-5i; Tue, 15 Dec 2020 13:55:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54234.94131; Tue, 15 Dec 2020 13:55:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnV-0002DO-2f; Tue, 15 Dec 2020 13:55:25 +0000
Received: by outflank-mailman (input) for mailman id 54234;
 Tue, 15 Dec 2020 13:55:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnT-0002Ct-PK
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnT-0007np-N2
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnT-0000wA-MM
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WsZtj1QgsyeldAZU6eBFoh0G6TrWvhn5qXcHAjlXe5s=; b=e1GTSjehJQJA1qewEL1rBEfBuK
	U72U8fSIb1uGrsee9Nzigk1zqDt2zI3u8YelmRIPx4stB7i0SV8ZgisR60wO70P8R0mZJw9O+2DaD
	TYWLLjuWfkWhNQ9DuZNp9R0SmAKZfH2KbzZcHjrAI69TQt5Y4Fb0xdHm3lgQSMHLVdk4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpAnT-0000wA-MM@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:23 +0000

commit bdd36b63225a3be7cf9a686847dee4d0c1678094
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:54 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index be9c62f27f..d7432c6597 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54235.94135 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnf-0002El-7L; Tue, 15 Dec 2020 13:55:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54235.94135; Tue, 15 Dec 2020 13:55:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnf-0002Ed-4I; Tue, 15 Dec 2020 13:55:35 +0000
Received: by outflank-mailman (input) for mailman id 54235;
 Tue, 15 Dec 2020 13:55:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnd-0002ET-QQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnd-0007oJ-Pl
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnd-0000xO-P3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gELb6W0x3L0J8KljZ+Zvl9jZO7DafqddWjhBqvDpcqk=; b=nvzEwHGfKyHnqvPjx8bCCIA1jU
	S1NCTmDwOPxPdJaPXaauMXlo+o4eMaUXhVxwUCNZyxdvX5fvMD3gRobSjo4gRDsomrAtPanF5i8bE
	Nz+rEUMjDij0GUF4bs26glFUTpq6CaxQiFRucv3g+dnSN02Td5ky8RBa6Uc7TBNUzHKY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpAnd-0000xO-P3@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:33 +0000

commit a4c2c94e8ba8e9dd99b98b9dbe5f112baa76c1c5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:59 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f374abe998..c3c8ea2f4b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6375a1c889..98d368d52f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e89c1aff04..f3d95e8897 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -89,19 +89,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (String.sub buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 49fc18bf19..32c3b1c0f1 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54236.94139 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnp-0002GB-8u; Tue, 15 Dec 2020 13:55:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54236.94139; Tue, 15 Dec 2020 13:55:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnp-0002G4-5w; Tue, 15 Dec 2020 13:55:45 +0000
Received: by outflank-mailman (input) for mailman id 54236;
 Tue, 15 Dec 2020 13:55:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnn-0002Fu-TQ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnn-0007oX-Sc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnn-0000z7-Rt
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=pVbsv9hmhZX0wW29VODFxSkUJtg4XG7O+8ToLNirWwI=; b=MMcnFf1Lr712X/7unnPtvXSIf9
	SiY18yNL7U+6aMkvs3zEdkNNbCwrqhoH3fcpg5wfcN521yAF36EomXZezBU6F4gJRyZ6cZKTm1lIK
	cbWCsB8rDv2j5jz+IHbtP697WUbgEmDvWsBBZzUZ633iCjIdXKTll/Bgj+LkynLKkGKg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpAnn-0000z7-Rt@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:43 +0000

commit 7e16a0e884c245fbe34cc6bfe047230a432dbbd5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:03 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 ++++++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 ++++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++++-----
 tools/ocaml/xenstored/process.ml     | 36 ++++++++++++++++++++++--------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 84 insertions(+), 28 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index d7432c6597..1389d971c2 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index ae7692819d..020b875dcd 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec x = function
 		| None         -> ()
 		| Some watches -> 
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index 0c0d03d0c4..fab76829cf 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -333,3 +337,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index c3c8ea2f4b..3cd0097db9 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			Connection.end_transaction c tid None
 		)
 
-let do_watch con t domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) = 
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con t domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -414,7 +419,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +438,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 23e7ccff1b..9e9e28db9b 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 32c3b1c0f1..e9f471846f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:55:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:55:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54237.94142 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnz-0002HS-B4; Tue, 15 Dec 2020 13:55:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54237.94142; Tue, 15 Dec 2020 13:55:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAnz-0002HJ-7r; Tue, 15 Dec 2020 13:55:55 +0000
Received: by outflank-mailman (input) for mailman id 54237;
 Tue, 15 Dec 2020 13:55:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAny-0002H8-03
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnx-0007oi-VY
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAnx-000107-Uj
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:55:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QqTDuPv5vfdd0TtZh3DPZF+ql7DmXLZ1eBTCR2m3T/0=; b=up3w/SguADWg9OIZiZyLgRF1yL
	6PCCCdjV6+58NmieRnw/x9Qo6umZip7koOjPQM94/Z6eqYbOe4bi1vgPln8aneRq//Y2S7uiwfH1J
	N8tHW9FCKlQQrsN1qGIlxo9oniNcXP3IZxvtaF7JqD3WwWD8bC6Y244aMXeM0EBZ+pzY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpAnx-000107-Uj@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:55:53 +0000

commit e644edc7f2b6e58a70cd4668bf9fa482d5154bb5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:08 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 1389d971c2..698f721345 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 6579b84448..d5d4f00de8 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index e9f471846f..30fc874327 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54238.94147 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAo9-0002Jz-EU; Tue, 15 Dec 2020 13:56:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54238.94147; Tue, 15 Dec 2020 13:56:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAo9-0002Js-B3; Tue, 15 Dec 2020 13:56:05 +0000
Received: by outflank-mailman (input) for mailman id 54238;
 Tue, 15 Dec 2020 13:56:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAo8-0002JS-3c
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAo8-0007qc-2O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAo8-000110-1b
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OkRRqkN3mT72ZC0VsnqpYtxUsUswXKfCe/HqFs0ABJA=; b=qAoAEPqtXjKFSheBXfT2h59UB3
	1ClO3jKjJdVzLTZf1gG1/ouQkj2C7aDZjtlX7NNVPfUDS25NWpYUg0NjzzzAbP1qdvmdc/8DDAZbX
	LLdPEJ1q/i0TwI3nNlDlqGPhyx+beYUIRFe6mMVjki3UD0NppBEkmTk4VPwueU6oeVuo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpAo8-000110-1b@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:04 +0000

commit fcc17dc279d76a00dfd3d7a5c0537c32f928002b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:44:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:27 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..4fbe5c759c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..f5e7af46e8 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -301,58 +323,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -399,15 +447,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -518,8 +572,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -662,8 +716,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -744,6 +800,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54240.94151 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoJ-0002La-G5; Tue, 15 Dec 2020 13:56:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54240.94151; Tue, 15 Dec 2020 13:56:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoJ-0002LT-D4; Tue, 15 Dec 2020 13:56:15 +0000
Received: by outflank-mailman (input) for mailman id 54240;
 Tue, 15 Dec 2020 13:56:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoI-0002LL-64
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoI-0007qk-5O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoI-00011w-4V
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4bbSSB3aulzWyFPTzfvXa85Tc5faIIJ9tBp5XGM1XH8=; b=K5lNtkwCx1zBfydM/X0etp8EDI
	mU1ENXWau1XEBbwZ6kYchtKSTlzzx9GhcCWvzr81IUNJCuURwXd2W7+6kZLqXDaTnSifAjLPpNh6/
	ySF1T33z/KUgVxfHQv1yIEpM/4df+ocjSDulGtNFjO41MAxSIPqCr53YpnAf+ejqtcyQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpAoI-00011w-4V@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:14 +0000

commit 66e2db1d6ed6dc261658931547454c8065ca9287
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:32 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 3cd0097db9..6a998f8764 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches 
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 98d368d52f..6bbbd05552 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 30fc874327..183dd2754b 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54241.94155 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoT-0002NX-IG; Tue, 15 Dec 2020 13:56:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54241.94155; Tue, 15 Dec 2020 13:56:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoT-0002NN-Ep; Tue, 15 Dec 2020 13:56:25 +0000
Received: by outflank-mailman (input) for mailman id 54241;
 Tue, 15 Dec 2020 13:56:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoS-0002Mw-9u
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoS-0007qt-8O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoS-00013L-7Y
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9sLWP+w+htlX+pSKb8IHfg3dAFG2qvT9Fk+D/ZlP4kM=; b=ONFaq5c5AOp9ZM2e+7zRXg9YoU
	6Rf+MlBBXozTalLsr9Phz2laoWMzjYWWb7T25loONFkZ/HrWDG/XAcXs/mSTZb16K13DJ5B5NLIOi
	jLodlcJgbErt1CB90KSqnxVZU0oeCRaycDgACbSvq6HHxiXMAZ5v/+5xmxU48FUPurNM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpAoS-00013L-7Y@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:24 +0000

commit 17b26b823b00a2993ea3f7517bff2e236c939103
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:01 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 6 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index d5d4f00de8..bef633090b 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index f3d95e8897..02639c77e9 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -94,7 +94,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -102,4 +102,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 183dd2754b..70f1bf8d2e 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54242.94159 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoe-0002Pp-LB; Tue, 15 Dec 2020 13:56:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54242.94159; Tue, 15 Dec 2020 13:56:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAoe-0002Ph-Hk; Tue, 15 Dec 2020 13:56:36 +0000
Received: by outflank-mailman (input) for mailman id 54242;
 Tue, 15 Dec 2020 13:56:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoc-0002Ox-Co
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoc-0007rH-CA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAoc-00014A-AU
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8E2iBr8Mf/NPUd1V4/cmvgDohvaxDcGf0qvn+P03uyo=; b=hwckpvqplFlODkAmFyn1P61hbe
	/mKJpN0nDHnG5s/8X+j3in/vS22yv8Sm2hqYHt1TAOKfNbGGwugeb6bcdD0Z2caQRe3R0ePQFP5Mu
	NRQ9P/F4ChOzBX6ScVoqnAE+BWUF6E13zBTB9Mo1PAoE51sZolHN0rnRmeAA7pmSRYGE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpAoc-00014A-AU@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:34 +0000

commit 03569ab92888b2ca217747ac5d58aa1259fb0c6a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:45:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:08 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 4fbe5c759c..e8f2057a32 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54245.94163 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAon-0002Rj-MD; Tue, 15 Dec 2020 13:56:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54245.94163; Tue, 15 Dec 2020 13:56:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAon-0002Rb-JI; Tue, 15 Dec 2020 13:56:45 +0000
Received: by outflank-mailman (input) for mailman id 54245;
 Tue, 15 Dec 2020 13:56:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAom-0002RS-Ft
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAom-0007rP-FD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAom-00015F-EG
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/KtxJ8d+B9n7TXrX3VWmVT4LZwPn63gz7YvW6I36Kww=; b=BxsQ6Esy/7wBW/FFjyzhGf31TP
	MvPETp3AWKIGGR1KYRcGryto//0QjLk2AJGsc1OUjLjWCQsk4SBgMtDxAlmI/ogeLep6MTY+fQK1w
	BkndbKTTSkElOTu60fn2tspTjg2zmxKOLQMRHfwQUPta80zQBTK+KHT4pnBoe0p6FVhE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpAom-00015F-EG@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:44 +0000

commit 3056f89163d8ef7a56a6c1881519d4abc6193685
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:45:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:13 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index e8f2057a32..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index e4966c89e3..6d1d0460b4 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -82,6 +82,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index f5e7af46e8..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -298,6 +298,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -315,6 +319,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:56:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:56:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54246.94168 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAox-0002Ub-Oa; Tue, 15 Dec 2020 13:56:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54246.94168; Tue, 15 Dec 2020 13:56:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAox-0002UR-Ku; Tue, 15 Dec 2020 13:56:55 +0000
Received: by outflank-mailman (input) for mailman id 54246;
 Tue, 15 Dec 2020 13:56:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAow-0002TW-Jo
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAow-0007rX-Ii
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAow-00016K-HS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:56:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=M3MV281HvhgeH7gt4cgWVR6Wx/p9nG99VBIPmR1pBNU=; b=lVOxHDoZ2ixmmbtweT0gIaivPh
	abOF+1VfvAD0zTZrTMIgSAP6QA7EPVGhSPojUVLq6xuBr93t5SlCohCqpWKa23cwDLiSGKDuUL9l0
	IT3T8kOUeG4uKOby//QdIMjt+M/ygdXRafa1rCdJTJ6pkFr15DeOtcL1HLXSeTh9OeNI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpAow-00016K-HS@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:56:54 +0000

commit 7073b82830378bf21137e57357cb1c1cf6f8954d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:35 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 020b875dcd..4e69de1d42 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 6a998f8764..12ad66fce6 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con t domains cons data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:57:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:57:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54247.94170 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAp7-0002Vu-PP; Tue, 15 Dec 2020 13:57:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54247.94170; Tue, 15 Dec 2020 13:57:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpAp7-0002Vn-MX; Tue, 15 Dec 2020 13:57:05 +0000
Received: by outflank-mailman (input) for mailman id 54247;
 Tue, 15 Dec 2020 13:57:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAp6-0002VY-Ml
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAp6-0007rv-Lz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpAp6-00017B-Ky
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=3EWXWzZ9o1UGts0IW7phd7aiIpl5WeFi+CTbZSRnfMg=; b=A1dvRm140edshMShF45qhDHJCD
	Pj2eQCi2PH/xsiuAGfp0ezo/nPkzpRkPQDfOq12EAAsiFLjkQ8ZlUaOGBMW3JTKhzNkgPNRrYzVmv
	Y0KF5AcqcvV0UGw7SoL5RkmqiEj7UfwChfDGpnCSxgNxefy9u3417Pj/nbsYVeeTQoBY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpAp6-00017B-Ky@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:57:04 +0000

commit fef52f19ed59bbb379b04a711079c67aaaf788d4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:47 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6bbbd05552..2a694562bb 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:57:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:57:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54248.94174 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApH-0002XB-Qx; Tue, 15 Dec 2020 13:57:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54248.94174; Tue, 15 Dec 2020 13:57:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApH-0002X3-O7; Tue, 15 Dec 2020 13:57:15 +0000
Received: by outflank-mailman (input) for mailman id 54248;
 Tue, 15 Dec 2020 13:57:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApG-0002Ws-Q1
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApG-0007s2-PE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApG-000182-OV
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KeqnlqX1uP6ml6jIWeB//NigNeLNNUegZivkfjRUdHA=; b=vWQ7gFkqry+fQh+gnxK5QZYikN
	owOouTRu4I7Qu5bHIvsxLZ39UEk2DbLYenJdrzmeBCTi1ivjWfcqF0kNFxRoqj61dFHMynNIMAQmd
	mHxgYFxRC/q0IluLqH0IqNuVdfnrJLUz4ootbnbpLJ9GtX+9Q0yslGM+XHbvZiFUyIUg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpApG-000182-OV@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:57:14 +0000

commit cbc06ee4280371f78f5858cd613c8d1e2a53ecd3
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:46:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:46:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 7ae7266c5f..2c59863342 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -121,7 +121,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -161,11 +161,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -560,7 +555,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1765,20 +1760,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 25fc9f2288..0365d6bfc2 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1086,8 +1086,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(hvm_msr_tsc_aux(v));
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     bool_t debug_state = v->domain->debugger_attached;
     bool_t vcpu_guestmode = 0;
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index e18ebbae9e..a500117781 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1785,8 +1785,9 @@ void vmx_vmentry_failure(void)
     domain_crash_synchronous();
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
 
     if ( v->arch.hvm_vmx.active_cpu == smp_processor_id() )
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 22269023bf..8834190feb 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -64,7 +64,7 @@ custom_runtime_param("pcid", parse_pcid);
 #undef page_to_mfn
 #define page_to_mfn(pg) _mfn(__page_to_mfn(pg))
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b7860a772f..2c15df54bd 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 5afaf6b9de..bd31fada49 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -330,7 +330,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
     /* nestedhvm: translate l2 guest physical to host physical */
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index aad25335eb..a05a0d4d62 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:57:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:57:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54249.94179 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApR-0002ZH-Tw; Tue, 15 Dec 2020 13:57:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54249.94179; Tue, 15 Dec 2020 13:57:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApR-0002ZA-Qv; Tue, 15 Dec 2020 13:57:25 +0000
Received: by outflank-mailman (input) for mailman id 54249;
 Tue, 15 Dec 2020 13:57:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApQ-0002Yf-Tc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApQ-0007sA-S6
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApQ-00018y-RL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aQCFRQa96LJnytJFq/OQs9z8uA6+6fBwHG+m3FcTSlw=; b=M2fPywTPYqqGUAj6I5ZSXHSVYM
	b3PWI3d3op5R1N6y7/gsApcQMP5ahvRD2TMXRX/ACRACUukgtdHaP8wUEzBqLV5otGfZ3L7d1aL4a
	A8J4UV1e3p09JShyukUMlcPqnteZcYftCbwk8t3frmSEeCEJWmPurBfJjsr8JKcgCB/Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpApQ-00018y-RL@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:57:24 +0000

commit 136ac884e621a74b6b6168f474ae751a0ec690ab
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:47:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:47:04 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 0a90a8404d..ab9e496696 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -227,6 +227,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -452,6 +456,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -462,10 +467,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 13:57:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 13:57:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54250.94182 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApb-0002bB-VQ; Tue, 15 Dec 2020 13:57:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54250.94182; Tue, 15 Dec 2020 13:57:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpApb-0002b3-Sb; Tue, 15 Dec 2020 13:57:35 +0000
Received: by outflank-mailman (input) for mailman id 54250;
 Tue, 15 Dec 2020 13:57:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApb-0002au-0D
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApa-0007sb-Vl
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpApa-00019h-U6
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 13:57:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/jFXnvc3/gKLomlhVyfcruWRWH5gmXsnJuaH6C/8MNU=; b=dTU5hwvCUKIaR7MKt9RShTDxPJ
	kWfap1B4pqXS77CcgLldgYpb2M3vTTSS6INTQUoz0eng+wGSRpzraH74rYv1t0tjakUs/OzwzXfYC
	3MpAr98pgKoaAdFsmE03JElVSUvZxu173djtlWDAq5qtoO4zJGLzJPZliDJ66z2kbaVM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.10] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpApa-00019h-U6@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 13:57:34 +0000

commit 6ea37c69c7d3948d9bb6f217235ae8bd767e8c46
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:47:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:47:28 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index ab9e496696..454ca40743 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -590,6 +597,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.10


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:00:12 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:00:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54348.94370 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkA-0007ck-Ux; Tue, 15 Dec 2020 16:00:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54348.94370; Tue, 15 Dec 2020 16:00:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkA-0007cN-RM; Tue, 15 Dec 2020 16:00:06 +0000
Received: by outflank-mailman (input) for mailman id 54348;
 Tue, 15 Dec 2020 16:00:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCk9-0007Rs-LP
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCk9-00026t-IL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCk9-0002b2-Gv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=A7UT2TonZkK/lj5WaH5GkVDj+ZGgntDgjeegnpw/I9E=; b=On6dU1zQbmLxHzlYe7EeW9EmTx
	I/1C4kTbG7119wkhggtwc0DQzVOhK6LZG09kmsnyb4lhIQVKhbXZw1FSIIUWvj0p9JSUXhiFJ1dFY
	2kxnz0G7x32jpWXguJrCbkOz5l4XL0RNkyIh4YYOsSd3hezy3puK5YtolCUWxg4INFD4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] examples: Add PVH example to config example list
Message-Id: <E1kpCk9-0002b2-Gv@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:00:05 +0000

commit 3e6944bf18461e3919ade89f11bcd735e8f992ec
Author:     Elliott Mitchell <ehem+xen@m5p.com>
AuthorDate: Mon Dec 14 18:35:32 2020 -0800
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:51:58 2020 +0000

    examples: Add PVH example to config example list
    
    Somewhat helpful to actually install the example configurations.
    
    Signed-off-by: Elliott Mitchell <ehem+xen@m5p.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/examples/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/examples/Makefile b/tools/examples/Makefile
index 2a6c5444d4..14e24f4cb3 100644
--- a/tools/examples/Makefile
+++ b/tools/examples/Makefile
@@ -6,6 +6,7 @@ XEN_READMES = README
 
 XEN_CONFIGS += xlexample.hvm
 XEN_CONFIGS += xlexample.pvlinux
+XEN_CONFIGS += xlexample.pvhlinux
 XEN_CONFIGS += xl.conf
 XEN_CONFIGS += cpupool
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:00:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:00:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54350.94375 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkL-0007lT-0g; Tue, 15 Dec 2020 16:00:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54350.94375; Tue, 15 Dec 2020 16:00:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkK-0007l1-TI; Tue, 15 Dec 2020 16:00:16 +0000
Received: by outflank-mailman (input) for mailman id 54350;
 Tue, 15 Dec 2020 16:00:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkJ-0007jo-NL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkJ-0002Bs-MZ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkJ-0002c3-Kf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=62gNaPFk69V3eq6QtjBxpIvLQvwwiH9HMMaUCS+IDgA=; b=qi/5hZrmrywX5Kk1oFYz0jCbFi
	hQsQQcYxBb17NFw5TbFvAmhb+GmF3AtQmnowGNN1kXblBueuudeq/dhIWc1b9Y/zc33BJLCdPV4H+
	oUpksJ/nyTjUr64D6QN5zoF5gTeILyIIY5bDoQXYAQuSQAU0fYMPGcGRNMcAKQsHSI28=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] MAINTAINERS: add me as maintainer for tools/xenstore/
Message-Id: <E1kpCkJ-0002c3-Kf@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:00:15 +0000

commit c6dc730e52abfba9cea4ccbfead1c494707bca57
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 8 11:30:26 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:54:44 2020 +0000

    MAINTAINERS: add me as maintainer for tools/xenstore/
    
    I have been the major contributor for C Xenstore the past few years.
    
    Add me as a maintainer for tools/xenstore/.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dab38a6a14..6dbd99aff4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -584,6 +584,13 @@ F:	xen/include/asm-x86/guest/hyperv-hcall.h
 F:	xen/include/asm-x86/guest/hyperv-tlfs.h
 F:	xen/include/asm-x86/hvm/viridian.h
 
+XENSTORE
+M:	Ian Jackson <iwj@xenproject.org>
+M:	Wei Liu <wl@xen.org>
+M:	Juergen Gross <jgross@suse.com>
+S:	Supported
+F:	tools/xenstore/
+
 XENTRACE
 M:	George Dunlap <george.dunlap@citrix.com>
 S:	Supported
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54352.94378 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkV-0007vD-1j; Tue, 15 Dec 2020 16:00:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54352.94378; Tue, 15 Dec 2020 16:00:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpCkU-0007v3-Uv; Tue, 15 Dec 2020 16:00:26 +0000
Received: by outflank-mailman (input) for mailman id 54352;
 Tue, 15 Dec 2020 16:00:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkT-0007ud-QO
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkT-0002C3-Pd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpCkT-0002cj-Oh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:00:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5R2VRIdCKK79SlK0AI/2JLu8vhagzsfyLjT2dt5xwHs=; b=xHwthiifnhLqzuxNn3KAmArNxh
	TJcglat42jfIUIiHfrpuM5GOVo7u14VT/wzZgih83J966MGYUa+qF/2CG+hZLDgyam1S7aqeHnWEm
	rtRyJFrpk7vbLMZ10incYvDsHjaPr1BLEifSYrcbxyNYWpxU/zz8EeP1xGJBmLPXUVvY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: rework path length check
Message-Id: <E1kpCkT-0002cj-Oh@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:00:25 +0000

commit 924bf8c793cb1fee303c83f50632c68426cf8f12
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 16:04:11 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:55:38 2020 +0000

    tools/xenstore: rework path length check
    
    The different fixed limits for absolute and relative path lengths of
    Xenstore nodes make it possible to create per-domain nodes via
    absolute paths which are not accessible using relative paths, as the
    two limits differ by 1024 characters.
    
    Instead of this weird limits use only one limit, which applies to the
    relative path length of per-domain nodes and to the absolute path
    length of all other nodes. This means, the path length check is
    applied to the path after removing a possible start of
    "/local/domain/<n>/" with <n> being a domain id.
    
    There has been the request to be able to limit the path lengths even
    more, so an additional quota is added which can be applied to path
    lengths. It is XENSTORE_REL_PATH_MAX (2048) per default, but can be
    set to lower values. This is done via the new "-M" or "--path-max"
    option when invoking xenstored.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xenstore/xenstored_core.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 746a1247b3..3082a36d3a 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -102,6 +102,7 @@ int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
 int quota_nb_perms_per_node = 5;
+int quota_max_path_len = XENSTORE_REL_PATH_MAX;
 
 void trace(const char *fmt, ...)
 {
@@ -734,6 +735,9 @@ static bool valid_chars(const char *node)
 
 bool is_valid_nodename(const char *node)
 {
+	int local_off = 0;
+	unsigned int domid;
+
 	/* Must start in /. */
 	if (!strstarts(node, "/"))
 		return false;
@@ -746,7 +750,10 @@ bool is_valid_nodename(const char *node)
 	if (strstr(node, "//"))
 		return false;
 
-	if (strlen(node) > XENSTORE_ABS_PATH_MAX)
+	if (sscanf(node, "/local/domain/%5u/%n", &domid, &local_off) != 1)
+		local_off = 0;
+
+	if (strlen(node) > local_off + quota_max_path_len)
 		return false;
 
 	return valid_chars(node);
@@ -806,6 +813,8 @@ static struct node *get_node_canonicalized(struct connection *conn,
 	if (!canonical_name)
 		canonical_name = &tmp_name;
 	*canonical_name = canonicalize(conn, ctx, name);
+	if (!*canonical_name)
+		return NULL;
 	return get_node(conn, ctx, *canonical_name, perm);
 }
 
@@ -1926,6 +1935,7 @@ static void usage(void)
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
 "  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
+"  -M, --path-max <chars>  limit the allowed Xenstore node path length,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1947,6 +1957,7 @@ static struct option options[] = {
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
 	{ "perm-nb", 1, NULL, 'A' },
+	{ "path-max", 1, NULL, 'M' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1969,7 +1980,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:M:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2014,6 +2025,10 @@ int main(int argc, char *argv[])
 		case 'A':
 			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
 			break;
+			quota_max_path_len = strtol(optarg, NULL, 10);
+			quota_max_path_len = min(XENSTORE_REL_PATH_MAX,
+						 quota_max_path_len);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54501.94728 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDG6-0005aZ-KE; Tue, 15 Dec 2020 16:33:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54501.94728; Tue, 15 Dec 2020 16:33:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDG6-0005aR-HG; Tue, 15 Dec 2020 16:33:06 +0000
Received: by outflank-mailman (input) for mailman id 54501;
 Tue, 15 Dec 2020 16:33:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDG6-0005aH-43
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDG6-0002pP-0z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDG5-0005EZ-WE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YU8gwiR4OELtcQSJaKsdEfUsKG5/m71grvRylJm2HnA=; b=jEc8nQNzeciZABcV2Qor0cs2Wk
	PRgOdUyGdbgi0yN3RX8i72qQiKa6U/zhP7iYrGP7coQbc26QWRiMKEvkW5naZFHajms/zSMsG2Mfd
	d6QzZoq7Dpjg5ErAJUfo60sNjs7q7qVFzr7Yi7pALAQvAO/hQOwk1/DeqHnaLE7f6sYU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools: allocate bitmaps in units of unsigned long
Message-Id: <E1kpDG5-0005EZ-WE@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:05 +0000

commit 8b90e311e0912b822621167621c515b41ea3d8e2
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Dec 9 16:54:49 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:23:14 2020 +0000

    tools: allocate bitmaps in units of unsigned long
    
    Allocate enough memory so that the returned pointer can be safely
    accessed as an array of unsigned long.
    
    The actual bitmap size in units of bytes, as returned by bitmap_size,
    remains unchanged.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/ctrl/xc_bitops.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/libs/ctrl/xc_bitops.h b/tools/libs/ctrl/xc_bitops.h
index 3d3a09772a..d6c5ea5138 100644
--- a/tools/libs/ctrl/xc_bitops.h
+++ b/tools/libs/ctrl/xc_bitops.h
@@ -21,7 +21,10 @@ static inline unsigned long bitmap_size(unsigned long nr_bits)
 
 static inline void *bitmap_alloc(unsigned long nr_bits)
 {
-    return calloc(1, bitmap_size(nr_bits));
+    unsigned long longs;
+
+    longs = (nr_bits + BITS_PER_LONG - 1) / BITS_PER_LONG;
+    return calloc(longs, sizeof(unsigned long));
 }
 
 static inline void bitmap_set(void *addr, unsigned long nr_bits)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54503.94733 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGG-0005ch-Mk; Tue, 15 Dec 2020 16:33:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54503.94733; Tue, 15 Dec 2020 16:33:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGG-0005cX-Io; Tue, 15 Dec 2020 16:33:16 +0000
Received: by outflank-mailman (input) for mailman id 54503;
 Tue, 15 Dec 2020 16:33:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGG-0005cP-68
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGG-0002pZ-50
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGG-0005F7-35
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wimFXf1ZgM1HUodv9Py69A35OLx+w3u4DO3XE4j7zcw=; b=Fz5dF3vWJ6RT+ZqlQdT5wcnxgU
	+tMgL31oEAoVOitvDt3R9Dg4GwP7r9j8efzrIAbFD/TziI1UbHAp0r8xUT+SLIDPnuv37U553n2cS
	+9kWNJFC8VbtcSSiSUP8oFL7tlJ2cjR6ERqbnqzra7FbZJCHCKsci9ZWGiqnkZT6GSK8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools: remove unused ORDER_LONG
Message-Id: <E1kpDGG-0005F7-35@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:16 +0000

commit 8862cb679cc23cb02fceaa897215f2ba58b3bed6
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Dec 9 16:54:50 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:23:17 2020 +0000

    tools: remove unused ORDER_LONG
    
    There are no users left, xenpaging has its own variant.
    The last user was removed with commit 11d0044a168994de85b9b328452292852aedc871
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/ctrl/xc_bitops.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tools/libs/ctrl/xc_bitops.h b/tools/libs/ctrl/xc_bitops.h
index d6c5ea5138..f0bac4a071 100644
--- a/tools/libs/ctrl/xc_bitops.h
+++ b/tools/libs/ctrl/xc_bitops.h
@@ -6,9 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* Needed by several includees, but no longer used for bitops. */
 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
 
 #define BITMAP_ENTRY(_nr,_bmap) ((_bmap))[(_nr) / 8]
 #define BITMAP_SHIFT(_nr) ((_nr) % 8)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54504.94736 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGR-0005er-OR; Tue, 15 Dec 2020 16:33:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54504.94736; Tue, 15 Dec 2020 16:33:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGR-0005ej-Kj; Tue, 15 Dec 2020 16:33:27 +0000
Received: by outflank-mailman (input) for mailman id 54504;
 Tue, 15 Dec 2020 16:33:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGQ-0005eE-BD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGQ-0002pl-9c
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGQ-0005Fj-8O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WpxF4gn5U531hVckIWRQsj1fFQSrnwgl+gQtldqAQrI=; b=pQtuV1A0pT3+/7LCtou0kwsmb0
	774ddzcLhNM1ZctcGdeOduMuIXOQ+KPxO+SNCmGNUyYKPG+rIcOgAPRUsQG4X/wLSgk35Un1EcfIj
	92pO0ZjgQ5klzb8r5jxblhXul86fvk/AvyFdNJxEZ/f+WrY1H/lh4M9sNcAJO54Rqc+U=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: s/pcidev/pci and remove DEFINE_DEVICE_TYPE_STRUCT_X
Message-Id: <E1kpDGQ-0005Fj-8O@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:26 +0000

commit e43780f15f13216c1ccef0bf143e089522661c21
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:09 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:16 2020 +0000

    libxl: s/pcidev/pci and remove DEFINE_DEVICE_TYPE_STRUCT_X
    
    The seemingly arbitrary use of 'pci' and 'pcidev' in the code in libxl_pci.c
    is confusing and also compromises use of some macros used for other device
    types. Indeed it seems that DEFINE_DEVICE_TYPE_STRUCT_X exists solely because
    of this duality.
    
    This patch purges use of 'pcidev' from the libxl internal code, but
    unfortunately the 'pcidevs' and 'num_pcidevs' fields in 'libxl_domain_config'
    are part of the API and need to be retained to avoid breaking callers,
    particularly libvirt.
    
    DEFINE_DEVICE_TYPE_STRUCT_X is still removed to avoid the special case in
    libxl_pci.c but DEFINE_DEVICE_TYPE_STRUCT is given an extra 'array' argument
    which is used to identify the fields in 'libxl_domain_config' relating to
    the device type.
    
    NOTE: Some of the more gross formatting errors (such as lack of spaces after
          keywords) that came into context have been fixed in libxl_pci.c.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h             |  10 +-
 tools/libs/light/libxl_9pfs.c     |   2 +-
 tools/libs/light/libxl_console.c  |   2 +-
 tools/libs/light/libxl_create.c   |   4 +-
 tools/libs/light/libxl_disk.c     |   2 +-
 tools/libs/light/libxl_internal.h |  29 +-
 tools/libs/light/libxl_nic.c      |   2 +-
 tools/libs/light/libxl_pci.c      | 570 +++++++++++++++++++-------------------
 tools/libs/light/libxl_pvcalls.c  |   2 +-
 tools/libs/light/libxl_usb.c      |   4 +-
 tools/libs/light/libxl_vdispl.c   |   2 +-
 tools/libs/light/libxl_vkb.c      |   2 +-
 tools/libs/light/libxl_vsnd.c     |   2 +-
 tools/libs/light/libxl_vtpm.c     |   2 +-
 tools/libs/util/libxlu_pci.c      |  36 +--
 15 files changed, 334 insertions(+), 337 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index eaffccb30f..733263522b 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -2307,15 +2307,15 @@ int libxl_device_pvcallsif_destroy(libxl_ctx *ctx, uint32_t domid,
 
 /* PCI Passthrough */
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
-                         libxl_device_pci *pcidev,
+                         libxl_device_pci *pci,
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
-                            libxl_device_pci *pcidev,
+                            libxl_device_pci *pci,
                             const libxl_asyncop_how *ao_how)
                             LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
-                             libxl_device_pci *pcidev,
+                             libxl_device_pci *pci,
                              const libxl_asyncop_how *ao_how)
                              LIBXL_EXTERNAL_CALLERS_ONLY;
 
@@ -2359,8 +2359,8 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pcidev, int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev, int rebind);
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
 
 /* CPUID handling */
diff --git a/tools/libs/light/libxl_9pfs.c b/tools/libs/light/libxl_9pfs.c
index e5c41e9a25..5ab0d3aa21 100644
--- a/tools/libs/light/libxl_9pfs.c
+++ b/tools/libs/light/libxl_9pfs.c
@@ -45,7 +45,7 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(p9)
 
 LIBXL_DEFINE_DEVICE_REMOVE(p9)
 
-DEFINE_DEVICE_TYPE_STRUCT(p9, 9PFS,
+DEFINE_DEVICE_TYPE_STRUCT(p9, 9PFS, p9s,
     .skip_attach = 1,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_p9,
diff --git a/tools/libs/light/libxl_console.c b/tools/libs/light/libxl_console.c
index 047d23d7ae..d8b2bc5465 100644
--- a/tools/libs/light/libxl_console.c
+++ b/tools/libs/light/libxl_console.c
@@ -725,7 +725,7 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(vfb)
 /* vfb */
 LIBXL_DEFINE_DEVICE_REMOVE(vfb)
 
-DEFINE_DEVICE_TYPE_STRUCT(vfb, VFB,
+DEFINE_DEVICE_TYPE_STRUCT(vfb, VFB, vfbs,
     .skip_attach = 1,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_vfb,
diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c
index 321a13e519..86f4a8369d 100644
--- a/tools/libs/light/libxl_create.c
+++ b/tools/libs/light/libxl_create.c
@@ -1809,7 +1809,7 @@ out:
 #define libxl__device_from_dtdev NULL
 #define libxl__device_dtdev_setdefault NULL
 #define libxl__device_dtdev_update_devid NULL
-static DEFINE_DEVICE_TYPE_STRUCT(dtdev, NONE);
+static DEFINE_DEVICE_TYPE_STRUCT(dtdev, NONE, dtdevs);
 
 const libxl__device_type *device_type_tbl[] = {
     &libxl__disk_devtype,
@@ -1817,7 +1817,7 @@ const libxl__device_type *device_type_tbl[] = {
     &libxl__vtpm_devtype,
     &libxl__usbctrl_devtype,
     &libxl__usbdev_devtype,
-    &libxl__pcidev_devtype,
+    &libxl__pci_devtype,
     &libxl__dtdev_devtype,
     &libxl__vdispl_devtype,
     &libxl__vsnd_devtype,
diff --git a/tools/libs/light/libxl_disk.c b/tools/libs/light/libxl_disk.c
index de183e0fb0..411ffeaca6 100644
--- a/tools/libs/light/libxl_disk.c
+++ b/tools/libs/light/libxl_disk.c
@@ -1374,7 +1374,7 @@ LIBXL_DEFINE_DEVICE_LIST(disk)
 
 #define libxl__device_disk_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT(disk, VBD,
+DEFINE_DEVICE_TYPE_STRUCT(disk, VBD, disks,
     .merge       = libxl_device_disk_merge,
     .dm_needed   = libxl_device_disk_dm_needed,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__disk_from_xenstore,
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index e26cda9b50..c2c5a9b926 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -1709,7 +1709,7 @@ _hidden int libxl__pci_topology_init(libxl__gc *gc,
 /* from libxl_pci */
 
 _hidden void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
-                                   libxl_device_pci *pcidev, bool starting,
+                                   libxl_device_pci *pci, bool starting,
                                    libxl__ao_device *aodev);
 _hidden void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
                                            libxl__multidev *);
@@ -3945,30 +3945,27 @@ struct libxl__device_type {
     device_set_xenstore_config_fn_t set_xenstore_config;
 };
 
-#define DEFINE_DEVICE_TYPE_STRUCT_X(name, sname, kind, ...)                    \
+#define DEFINE_DEVICE_TYPE_STRUCT(name, kind, array, ...)                      \
     const libxl__device_type libxl__ ## name ## _devtype = {                   \
-        .type          = LIBXL__DEVICE_KIND_ ## kind,                       \
-        .ptr_offset    = offsetof(libxl_domain_config, name ## s),             \
-        .num_offset    = offsetof(libxl_domain_config, num_ ## name ## s),     \
-        .dev_elem_size = sizeof(libxl_device_ ## sname),                       \
+        .type          = LIBXL__DEVICE_KIND_ ## kind,                          \
+        .ptr_offset    = offsetof(libxl_domain_config, array),                 \
+        .num_offset    = offsetof(libxl_domain_config, num_ ## array),         \
+        .dev_elem_size = sizeof(libxl_device_ ## name),                        \
         .add           = libxl__add_ ## name ## s,                             \
         .set_default   = (device_set_default_fn_t)                             \
-                         libxl__device_ ## sname ## _setdefault,               \
+                         libxl__device_ ## name ## _setdefault,                \
         .to_device     = (device_to_device_fn_t)libxl__device_from_ ## name,   \
-        .init          = (device_init_fn_t)libxl_device_ ## sname ## _init,    \
-        .copy          = (device_copy_fn_t)libxl_device_ ## sname ## _copy,    \
+        .init          = (device_init_fn_t)libxl_device_ ## name ## _init,     \
+        .copy          = (device_copy_fn_t)libxl_device_ ## name ## _copy,     \
         .dispose       = (device_dispose_fn_t)                                 \
-                         libxl_device_ ## sname ## _dispose,                   \
+                         libxl_device_ ## name ## _dispose,                    \
         .compare       = (device_compare_fn_t)                                 \
-                         libxl_device_ ## sname ## _compare,                   \
+                         libxl_device_ ## name ## _compare,                    \
         .update_devid  = (device_update_devid_fn_t)                            \
-                         libxl__device_ ## sname ## _update_devid,             \
+                         libxl__device_ ## name ## _update_devid,              \
         __VA_ARGS__                                                            \
     }
 
-#define DEFINE_DEVICE_TYPE_STRUCT(name, kind, ...)                             \
-    DEFINE_DEVICE_TYPE_STRUCT_X(name, name, kind, __VA_ARGS__)
-
 static inline void **libxl__device_type_get_ptr(
     const libxl__device_type *dt, const libxl_domain_config *d_config)
 {
@@ -3995,7 +3992,7 @@ extern const libxl__device_type libxl__nic_devtype;
 extern const libxl__device_type libxl__vtpm_devtype;
 extern const libxl__device_type libxl__usbctrl_devtype;
 extern const libxl__device_type libxl__usbdev_devtype;
-extern const libxl__device_type libxl__pcidev_devtype;
+extern const libxl__device_type libxl__pci_devtype;
 extern const libxl__device_type libxl__vdispl_devtype;
 extern const libxl__device_type libxl__p9_devtype;
 extern const libxl__device_type libxl__pvcallsif_devtype;
diff --git a/tools/libs/light/libxl_nic.c b/tools/libs/light/libxl_nic.c
index 0e5d120ae9..144e9e23e1 100644
--- a/tools/libs/light/libxl_nic.c
+++ b/tools/libs/light/libxl_nic.c
@@ -528,7 +528,7 @@ LIBXL_DEFINE_DEVICE_ADD(nic)
 LIBXL_DEFINE_DEVICES_ADD(nic)
 LIBXL_DEFINE_DEVICE_REMOVE(nic)
 
-DEFINE_DEVICE_TYPE_STRUCT(nic, VIF,
+DEFINE_DEVICE_TYPE_STRUCT(nic, VIF, nics,
     .update_config = libxl_device_nic_update_config,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__nic_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index bc5843b137..3340076d2c 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,51 +25,51 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pcidev_encode_bdf(libxl_device_pci *pcidev)
+static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pcidev->domain << 16;
-    value |= (pcidev->bus & 0xff) << 8;
-    value |= (pcidev->dev & 0x1f) << 3;
-    value |= (pcidev->func & 0x7);
+    value = pci->domain << 16;
+    value |= (pci->bus & 0xff) << 8;
+    value |= (pci->dev & 0x1f) << 3;
+    value |= (pci->func & 0x7);
 
     return value;
 }
 
-static void pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func, unsigned int vdevfn)
+static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                            unsigned int bus, unsigned int dev,
+                            unsigned int func, unsigned int vdevfn)
 {
-    pcidev->domain = domain;
-    pcidev->bus = bus;
-    pcidev->dev = dev;
-    pcidev->func = func;
-    pcidev->vdevfn = vdevfn;
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
 }
 
 static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             flexarray_t *back,
                                             int num,
-                                            const libxl_device_pci *pcidev)
+                                            const libxl_device_pci *pci)
 {
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
-    if (pcidev->vdevfn)
-        flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pcidev->vdevfn));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    if (pci->vdevfn)
+        flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
     flexarray_append(back,
               GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d",
-                             pcidev->msitranslate, pcidev->power_mgmt,
-                             pcidev->permissive));
+                             pci->msitranslate, pci->power_mgmt,
+                             pci->permissive));
     flexarray_append_pair(back, GCSPRINTF("state-%d", num), GCSPRINTF("%d", XenbusStateInitialising));
 }
 
-static void libxl__device_from_pcidev(libxl__gc *gc, uint32_t domid,
-                                      const libxl_device_pci *pcidev,
-                                      libxl__device *device)
+static void libxl__device_from_pci(libxl__gc *gc, uint32_t domid,
+                                   const libxl_device_pci *pci,
+                                   libxl__device *device)
 {
     device->backend_devid = 0;
     device->backend_domid = 0;
@@ -80,7 +80,7 @@ static void libxl__device_from_pcidev(libxl__gc *gc, uint32_t domid,
 }
 
 static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
-                                     const libxl_device_pci *pcidev,
+                                     const libxl_device_pci *pci,
                                      int num)
 {
     flexarray_t *front = NULL;
@@ -94,15 +94,15 @@ static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
     LOGD(DEBUG, domid, "Creating pci backend");
 
     /* add pci device */
-    libxl__device_from_pcidev(gc, domid, pcidev, &device);
+    libxl__device_from_pci(gc, domid, pci, &device);
 
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
     flexarray_append_pair(back, "online", "1");
     flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateInitialising));
     flexarray_append_pair(back, "domain", libxl__domid_to_name(gc, domid));
 
-    for (i = 0; i < num; i++, pcidev++)
-        libxl_create_pci_backend_device(gc, back, i, pcidev);
+    for (i = 0; i < num; i++, pci++)
+        libxl_create_pci_backend_device(gc, back, i, pci);
 
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num));
     flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", 0));
@@ -116,7 +116,7 @@ static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
 
 static int libxl__device_pci_add_xenstore(libxl__gc *gc,
                                           uint32_t domid,
-                                          const libxl_device_pci *pcidev,
+                                          const libxl_device_pci *pci,
                                           bool starting)
 {
     flexarray_t *back;
@@ -136,7 +136,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
                                                 LIBXL__DEVICE_KIND_PCI);
     num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
     if (!num_devs)
-        return libxl__create_pci_backend(gc, domid, pcidev, 1);
+        return libxl__create_pci_backend(gc, domid, pci, 1);
 
     libxl_domain_type domtype = libxl__domain_type(gc, domid);
     if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
@@ -151,7 +151,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
 
     LOGD(DEBUG, domid, "Adding new pci device to xenstore");
     num = atoi(num_devs);
-    libxl_create_pci_backend_device(gc, back, num, pcidev);
+    libxl_create_pci_backend_device(gc, back, num, pci);
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num + 1));
     if (!starting)
         flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateReconfiguring));
@@ -170,8 +170,8 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
         rc = libxl__get_domain_configuration(gc, domid, &d_config);
         if (rc) goto out;
 
-        device_add_domain_config(gc, &d_config, &libxl__pcidev_devtype,
-                                 pcidev);
+        device_add_domain_config(gc, &d_config, &libxl__pci_devtype,
+                                 pci);
 
         rc = libxl__dm_check_start(gc, &d_config, domid);
         if (rc) goto out;
@@ -201,7 +201,7 @@ out:
     return rc;
 }
 
-static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev)
+static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath;
@@ -231,8 +231,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pcidev->domain && bus == pcidev->bus &&
-            pcidev->dev == dev && pcidev->func == func) {
+        if (domain == pci->domain && bus == pci->bus &&
+            pci->dev == dev && pci->func == func) {
             break;
         }
     }
@@ -350,7 +350,7 @@ static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int
                     *list = realloc(*list, sizeof(libxl_device_pci) * ((*num) + 1));
                     if (*list == NULL)
                         return ERROR_NOMEM;
-                    pcidev_struct_fill(*list + *num, dom, bus, dev, func, 0);
+                    pci_struct_fill(*list + *num, dom, bus, dev, func, 0);
                     (*num)++;
                 }
             }
@@ -361,8 +361,8 @@ static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int
     return 0;
 }
 
-static int is_pcidev_in_array(libxl_device_pci *assigned, int num_assigned,
-                       int dom, int bus, int dev, int func)
+static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
+                           int dom, int bus, int dev, int func)
 {
     int i;
 
@@ -383,7 +383,7 @@ static int is_pcidev_in_array(libxl_device_pci *assigned, int num_assigned,
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
 static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
-                           libxl_device_pci *pcidev)
+                           libxl_device_pci *pci)
 {
     int rc, fd;
     char *buf;
@@ -394,8 +394,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus,
-                    pcidev->dev, pcidev->func);
+    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
+                    pci->dev, pci->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -411,7 +411,7 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcidevs = NULL, *new, *assigned;
+    libxl_device_pci *pcis = NULL, *new, *assigned;
     struct dirent *de;
     DIR *dir;
     int r, num_assigned;
@@ -436,40 +436,40 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        if (is_pcidev_in_array(assigned, num_assigned, dom, bus, dev, func))
+        if (is_pci_in_array(assigned, num_assigned, dom, bus, dev, func))
             continue;
 
-        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcidevs = new;
-        new = pcidevs + *num;
+        pcis = new;
+        new = pcis + *num;
 
         memset(new, 0, sizeof(*new));
-        pcidev_struct_fill(new, dom, bus, dev, func, 0);
+        pci_struct_fill(new, dom, bus, dev, func, 0);
         (*num)++;
     }
 
     closedir(dir);
 out:
     GC_FREE;
-    return pcidevs;
+    return pcis;
 }
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pcidev->domain,
-                           pcidev->bus,
-                           pcidev->dev,
-                           pcidev->func);
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -483,7 +483,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pcidev) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -495,11 +495,11 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
     return 0;
 }
 
-static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
+static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -507,7 +507,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -515,18 +515,18 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
     return pci_device_vendor;
 }
 
-static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
+static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -534,7 +534,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -542,25 +542,25 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
     return pci_device_device;
 }
 
-static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
+static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                     pci->domain, pci->bus, pci->dev, pci->func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -569,7 +569,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
     }
 
@@ -589,15 +589,15 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
     unsigned long class;
 
     for (i = 0 ; i < d_config->num_pcidevs ; i++) {
-        libxl_device_pci *pcidev = &d_config->pcidevs[i];
-        pt_vendor = sysfs_dev_get_vendor(gc, pcidev);
-        pt_device = sysfs_dev_get_device(gc, pcidev);
+        libxl_device_pci *pci = &d_config->pcidevs[i];
+        pt_vendor = sysfs_dev_get_vendor(gc, pci);
+        pt_device = sysfs_dev_get_device(gc, pci);
 
         if (pt_vendor == 0xffff || pt_device == 0xffff ||
             pt_vendor != 0x8086)
             continue;
 
-        if (sysfs_dev_get_class(gc, pcidev, &class))
+        if (sysfs_dev_get_class(gc, pci, &class))
             continue;
         if (class == 0x030000)
             return true;
@@ -621,8 +621,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for pcidev's BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pcidev)
+/* Scan through /sys/.../pciback/slots looking for pci's BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
 {
     FILE *f;
     int rc = 0;
@@ -635,11 +635,11 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pcidev)
         return ERROR_FAIL;
     }
 
-    while(fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func)==4) {
-        if(dom == pcidev->domain
-           && bus == pcidev->bus
-           && dev == pcidev->dev
-           && func == pcidev->func) {
+    while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
+        if (dom == pci->domain
+            && bus == pci->bus
+            && dev == pci->dev
+            && func == pci->func) {
             rc = 1;
             goto out;
         }
@@ -649,7 +649,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
 {
     char * spath;
     int rc;
@@ -665,8 +665,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pcidev->domain, pcidev->bus,
-                      pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus,
+                      pci->dev, pci->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -677,40 +677,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
 {
     int rc;
 
-    if ( (rc=pciback_dev_has_slot(gc, pcidev)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcidev) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pcidev, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pcidev) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -721,49 +721,49 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pcidev)
 #define PCIBACK_INFO_PATH "/libxl/pciback"
 
 static void pci_assignable_driver_path_write(libxl__gc *gc,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             char *driver_path)
 {
     char *path;
 
     path = GCSPRINTF(PCIBACK_INFO_PATH"/"PCI_BDF_XSPATH"/driver_path",
-                     pcidev->domain,
-                     pcidev->bus,
-                     pcidev->dev,
-                     pcidev->func);
+                     pci->domain,
+                     pci->bus,
+                     pci->dev,
+                     pci->func);
     if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", driver_path) < 0 ) {
         LOGE(WARN, "Write of %s to node %s failed.", driver_path, path);
     }
 }
 
 static char * pci_assignable_driver_path_read(libxl__gc *gc,
-                                              libxl_device_pci *pcidev)
+                                              libxl_device_pci *pci)
 {
     return libxl__xs_read(gc, XBT_NULL,
                           GCSPRINTF(
                            PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH "/driver_path",
-                           pcidev->domain,
-                           pcidev->bus,
-                           pcidev->dev,
-                           pcidev->func));
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func));
 }
 
 static void pci_assignable_driver_path_remove(libxl__gc *gc,
-                                              libxl_device_pci *pcidev)
+                                              libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
     xs_rm(ctx->xsh, XBT_NULL,
           GCSPRINTF(PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH,
-                    pcidev->domain,
-                    pcidev->bus,
-                    pcidev->dev,
-                    pcidev->func) );
+                    pci->domain,
+                    pci->bus,
+                    pci->dev,
+                    pci->func) );
 }
 
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -773,10 +773,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pcidev->domain;
-    bus = pcidev->bus;
-    dev = pcidev->dev;
-    func = pcidev->func;
+    dom = pci->domain;
+    bus = pci->bus;
+    dev = pci->dev;
+    func = pci->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -786,7 +786,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pcidev);
+    rc = pciback_dev_is_assigned(gc, pci);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
@@ -796,7 +796,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pcidev, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -805,9 +805,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_assignable_driver_path_write(gc, pcidev, driver_path);
+            pci_assignable_driver_path_write(gc, pci, driver_path);
         } else if ( (driver_path =
-                     pci_assignable_driver_path_read(gc, pcidev)) != NULL ) {
+                     pci_assignable_driver_path_read(gc, pci)) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -815,10 +815,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_assignable_driver_path_remove(gc, pcidev);
+        pci_assignable_driver_path_remove(gc, pci);
     }
 
-    if ( pciback_dev_assign(gc, pcidev) ) {
+    if ( pciback_dev_assign(gc, pci) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
@@ -829,7 +829,7 @@ quarantine:
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pcidev_encode_bdf(pcidev),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -840,7 +840,7 @@ quarantine:
 }
 
 static int libxl__device_pci_assignable_remove(libxl__gc *gc,
-                                               libxl_device_pci *pcidev,
+                                               libxl_device_pci *pci,
                                                int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -848,24 +848,24 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pcidev_encode_bdf(pcidev));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcidev->domain, pcidev->bus,
-            pcidev->dev, pcidev->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
+            pci->dev, pci->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc=pciback_dev_is_assigned(gc, pcidev)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pcidev);
+        pciback_dev_unassign(gc, pci);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_assignable_driver_path_read(gc, pcidev);
+    driver_path = pci_assignable_driver_path_read(gc, pci);
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -873,12 +873,12 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pcidev) < 0 ) {
+                                 pci) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_assignable_driver_path_remove(gc, pcidev);
+            pci_assignable_driver_path_remove(gc, pci);
         }
     } else {
         if ( rebind ) {
@@ -890,26 +890,26 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     return 0;
 }
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pcidev,
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
                                     int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_add(gc, pcidev, rebind);
+    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev,
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
                                        int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_remove(gc, pcidev, rebind);
+    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
 
     GC_FREE;
     return rc;
@@ -920,7 +920,7 @@ int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev,
  * driver. It also initialises a bit-mask of which function numbers are present
  * on that device.
 */
-static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pcidev, unsigned int *func_mask)
+static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigned int *func_mask)
 {
     struct dirent *de;
     DIR *dir;
@@ -940,11 +940,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pcidev, unsi
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pcidev->domain != dom )
+        if ( pci->domain != dom )
             continue;
-        if ( pcidev->bus != bus )
+        if ( pci->bus != bus )
             continue;
-        if ( pcidev->dev != dev )
+        if ( pci->dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -979,7 +979,7 @@ static int pci_ins_check(libxl__gc *gc, uint32_t domid, const char *state, void
 }
 
 static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
-                                 libxl_device_pci *pcidev)
+                                 libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc = 0;
@@ -991,15 +991,15 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    if (pcidev->vdevfn) {
+    if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pcidev->domain, pcidev->bus, pcidev->dev,
-                         pcidev->func, pcidev->vdevfn, pcidev->msitranslate,
-                         pcidev->power_mgmt);
+                         pci->domain, pci->bus, pci->dev,
+                         pci->func, pci->vdevfn, pci->msitranslate,
+                         pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pcidev->domain,  pcidev->bus, pcidev->dev,
-                         pcidev->func, pcidev->msitranslate, pcidev->power_mgmt);
+                         pci->domain,  pci->bus, pci->dev,
+                         pci->func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1010,7 +1010,7 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     if ( rc < 0 )
         LOGD(ERROR, domid, "qemu refused to add device: %s", vdevfn);
-    else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) {
+    else if ( sscanf(vdevfn, "0x%x", &pci->vdevfn) != 1 ) {
         LOGD(ERROR, domid, "wrong format for the vdevfn: '%s'", vdevfn);
         rc = -1;
     }
@@ -1054,7 +1054,7 @@ typedef struct pci_add_state {
     libxl__xswait_state xswait;
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
-    libxl_device_pci *pcidev;
+    libxl_device_pci *pci;
     int pci_domid;
 } pci_add_state;
 
@@ -1072,7 +1072,7 @@ static void pci_add_dm_done(libxl__egc *,
 
 static void do_pci_add(libxl__egc *egc,
                        libxl_domid domid,
-                       libxl_device_pci *pcidev,
+                       libxl_device_pci *pci,
                        pci_add_state *pas)
 {
     STATE_AO_GC(pas->aodev->ao);
@@ -1082,7 +1082,7 @@ static void do_pci_add(libxl__egc *egc,
     /* init pci_add_state */
     libxl__xswait_init(&pas->xswait);
     libxl__ev_qmp_init(&pas->qmp);
-    pas->pcidev = pcidev;
+    pas->pci = pci;
     pas->pci_domid = domid;
     libxl__ev_time_init(&pas->timeout);
 
@@ -1128,7 +1128,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1136,7 +1136,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
     if (rc)
         goto out;
 
-    rc = qemu_pci_add_xenstore(gc, domid, pcidev);
+    rc = qemu_pci_add_xenstore(gc, domid, pci);
 out:
     pci_add_dm_done(egc, pas, rc); /* must be last */
 }
@@ -1149,7 +1149,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
     libxl__ev_qmp *const qmp = &pas->qmp;
 
     rc = libxl__ev_time_register_rel(ao, &pas->timeout,
@@ -1160,14 +1160,14 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+                           pci->bus, pci->dev, pci->func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pcidev->domain,
-                           pcidev->bus, pcidev->dev, pcidev->func);
-    if (pcidev->vdevfn) {
+                           "%04x:%02x:%02x.%01x", pci->domain,
+                           pci->bus, pci->dev, pci->func);
+    if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
-                               PCI_SLOT(pcidev->vdevfn),
-                               PCI_FUNC(pcidev->vdevfn));
+                               PCI_SLOT(pci->vdevfn),
+                               PCI_FUNC(pci->vdevfn));
     }
     /*
      * Version of QEMU prior to the XSA-131 fix did not support
@@ -1179,7 +1179,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
      * set the permissive flag if it is true. Users of older QEMU
      * have no reason to set the flag so this is ok.
      */
-    if (pcidev->permissive)
+    if (pci->permissive)
         libxl__qmp_param_add_bool(gc, &args, "permissive", true);
 
     qmp->ao = pas->aodev->ao;
@@ -1230,7 +1230,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
     int dev_slot, dev_func;
 
     /* Convenience aliases */
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) goto out;
 
@@ -1251,7 +1251,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pcidev->bus, pcidev->dev, pcidev->func);
+                         pci->bus, pci->dev, pci->func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1283,7 +1283,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
              }
              dev_func = libxl__json_object_get_integer(o);
 
-             pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
+             pci->vdevfn = PCI_DEVFN(dev_slot, dev_func);
 
              rc = 0;
              goto out;
@@ -1331,7 +1331,7 @@ static void pci_add_dm_done(libxl__egc *egc,
 
     /* Convenience aliases */
     bool starting = pas->starting;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
     bool hvm = libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM;
 
     libxl__ev_qmp_dispose(gc, &pas->qmp);
@@ -1342,8 +1342,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1383,8 +1383,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain,
-                                pcidev->bus, pcidev->dev, pcidev->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                                pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1411,9 +1411,9 @@ static void pci_add_dm_done(libxl__egc *egc,
     fclose(f);
 
     /* Don't restrict writes to the PCI config space from this VM */
-    if (pcidev->permissive) {
+    if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1422,14 +1422,14 @@ static void pci_add_dm_done(libxl__egc *egc,
 
 out_no_irq:
     if (!isstubdom) {
-        if (pcidev->rdm_policy == LIBXL_RDM_RESERVE_POLICY_STRICT) {
+        if (pci->rdm_policy == LIBXL_RDM_RESERVE_POLICY_STRICT) {
             flag &= ~XEN_DOMCTL_DEV_RDM_RELAXED;
-        } else if (pcidev->rdm_policy != LIBXL_RDM_RESERVE_POLICY_RELAXED) {
+        } else if (pci->rdm_policy != LIBXL_RDM_RESERVE_POLICY_RELAXED) {
             LOGED(ERROR, domainid, "unknown rdm check flag.");
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev), flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1438,7 +1438,7 @@ out_no_irq:
     }
 
     if (!starting && !libxl_get_stubdom_id(CTX, domid))
-        rc = libxl__device_pci_add_xenstore(gc, domid, pcidev, starting);
+        rc = libxl__device_pci_add_xenstore(gc, domid, pci, starting);
     else
         rc = 0;
 out:
@@ -1493,7 +1493,7 @@ int libxl__device_pci_setdefault(libxl__gc *gc, uint32_t domid,
 }
 
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
-                         libxl_device_pci *pcidev,
+                         libxl_device_pci *pci,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -1504,24 +1504,24 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_ADD;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_add(egc, domid, pcidev, false, aodev);
+    libxl__device_pci_add(egc, domid, pci, false, aodev);
     return AO_INPROGRESS;
 }
 
-static int libxl_pcidev_assignable(libxl_ctx *ctx, libxl_device_pci *pcidev)
+static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
     for (i = 0; i < num; i++) {
-        if (pcidevs[i].domain == pcidev->domain &&
-            pcidevs[i].bus == pcidev->bus &&
-            pcidevs[i].dev == pcidev->dev &&
-            pcidevs[i].func == pcidev->func)
+        if (pcis[i].domain == pci->domain &&
+            pcis[i].bus == pci->bus &&
+            pcis[i].dev == pci->dev &&
+            pcis[i].func == pci->func)
             break;
     }
-    free(pcidevs);
+    free(pcis);
     return i != num;
 }
 
@@ -1535,7 +1535,7 @@ static void device_pci_add_done(libxl__egc *egc,
     pci_add_state *, int rc);
 
 void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
-                           libxl_device_pci *pcidev, bool starting,
+                           libxl_device_pci *pci, bool starting,
                            libxl__ao_device *aodev)
 {
     STATE_AO_GC(aodev->ao);
@@ -1545,9 +1545,9 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     int stubdomid = 0;
     pci_add_state *pas;
 
-    /* Store *pcidev to be used by callbacks */
-    aodev->device_config = pcidev;
-    aodev->device_type = &libxl__pcidev_devtype;
+    /* Store *pci to be used by callbacks */
+    aodev->device_config = pci;
+    aodev->device_type = &libxl__pci_devtype;
 
     GCNEW(pas);
     pas->aodev = aodev;
@@ -1556,29 +1556,29 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->callback = device_pci_add_stubdom_done;
 
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev));
+        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func,
+                 pci->domain, pci->bus, pci->dev, pci->func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
         }
     }
 
-    rc = libxl__device_pci_setdefault(gc, domid, pcidev, !starting);
+    rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pcidev->seize && !pciback_dev_is_assigned(gc, pcidev)) {
-        rc = libxl__device_pci_assignable_add(gc, pcidev, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
+        rc = libxl__device_pci_assignable_add(gc, pci, 1);
         if ( rc )
             goto out;
     }
 
-    if (!libxl_pcidev_assignable(ctx, pcidev)) {
+    if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         rc = ERROR_FAIL;
         goto out;
     }
@@ -1589,25 +1589,25 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
              "cannot determine if device is assigned, refusing to continue");
         goto out;
     }
-    if ( is_pcidev_in_array(assigned, num_assigned, pcidev->domain,
-                     pcidev->bus, pcidev->dev, pcidev->func) ) {
+    if ( is_pci_in_array(assigned, num_assigned, pci->domain,
+                         pci->bus, pci->dev, pci->func) ) {
         LOGD(ERROR, domid, "PCI device already attached to a domain");
         rc = ERROR_FAIL;
         goto out;
     }
 
-    libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pcidev_s;
+        libxl_device_pci *pci_s;
 
-        GCNEW(pcidev_s);
-        libxl_device_pci_init(pcidev_s);
-        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
+        GCNEW(pci_s);
+        libxl_device_pci_init(pci_s);
+        libxl_device_pci_copy(CTX, pci_s, pci);
         pas->callback = device_pci_add_stubdom_wait;
 
-        do_pci_add(egc, stubdomid, pcidev_s, pas); /* must be last */
+        do_pci_add(egc, stubdomid, pci_s, pas); /* must be last */
         return;
     }
 
@@ -1664,42 +1664,42 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
     /* Convenience aliases */
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = aodev->device_config;
+    libxl_device_pci *pci = aodev->device_config;
 
     if (rc) goto out;
 
-    orig_vdev = pcidev->vdevfn & ~7U;
+    orig_vdev = pci->vdevfn & ~7U;
 
-    if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( !(pcidev->vdevfn >> 3) ) {
+    if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
+        if ( !(pci->vdevfn >> 3) ) {
             LOGD(ERROR, domid, "Must specify a v-slot for multi-function devices");
             rc = ERROR_INVAL;
             goto out;
         }
-        if ( pci_multifunction_check(gc, pcidev, &pfunc_mask) ) {
+        if ( pci_multifunction_check(gc, pci, &pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
-        pcidev->vfunc_mask &= pfunc_mask;
+        pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pcidev->func);
+        pfunc_mask = (1 << pci->func);
     }
 
-    for(rc = 0, i = 7; i >= 0; --i) {
+    for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
-            if ( pcidev->vfunc_mask == pfunc_mask ) {
-                pcidev->func = i;
-                pcidev->vdevfn = orig_vdev | i;
-            }else{
+            if ( pci->vfunc_mask == pfunc_mask ) {
+                pci->func = i;
+                pci->vdevfn = orig_vdev | i;
+            } else {
                 /* if not passing through multiple devices in a block make
                  * sure that virtual function number 0 is always used otherwise
                  * guest won't see the device
                  */
-                pcidev->vdevfn = orig_vdev;
+                pci->vdevfn = orig_vdev;
             }
             pas->callback = device_pci_add_done;
-            do_pci_add(egc, domid, pcidev, pas); /* must be last */
+            do_pci_add(egc, domid, pci, pas); /* must be last */
             return;
         }
     }
@@ -1715,13 +1715,13 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = aodev->device_config;
+    libxl_device_pci *pci = aodev->device_config;
 
     if (rc) {
         LOGD(ERROR, domid,
              "libxl__device_pci_add  failed for "
              "PCI device %x:%x:%x.%x (rc %d)",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func,
+             pci->domain, pci->bus, pci->dev, pci->func,
              rc);
     }
     aodev->rc = rc;
@@ -1733,16 +1733,16 @@ typedef struct {
     libxl__ao_device *outer_aodev;
     libxl_domain_config *d_config;
     libxl_domid domid;
-} add_pcidevs_state;
+} add_pcis_state;
 
-static void add_pcidevs_done(libxl__egc *, libxl__multidev *, int rc);
+static void add_pcis_done(libxl__egc *, libxl__multidev *, int rc);
 
-static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
-                               libxl_domain_config *d_config,
-                               libxl__multidev *multidev)
+static void libxl__add_pcis(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                            libxl_domain_config *d_config,
+                            libxl__multidev *multidev)
 {
     AO_GC;
-    add_pcidevs_state *apds;
+    add_pcis_state *apds;
     int i;
 
     /* We need to start a new multidev in order to be able to execute
@@ -1752,7 +1752,7 @@ static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
     apds->outer_aodev = libxl__multidev_prepare(multidev);
     apds->d_config = d_config;
     apds->domid = domid;
-    apds->multidev.callback = add_pcidevs_done;
+    apds->multidev.callback = add_pcis_done;
     libxl__multidev_begin(ao, &apds->multidev);
 
     for (i = 0; i < d_config->num_pcidevs; i++) {
@@ -1764,11 +1764,11 @@ static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
     libxl__multidev_prepared(egc, &apds->multidev, 0);
 }
 
-static void add_pcidevs_done(libxl__egc *egc, libxl__multidev *multidev,
+static void add_pcis_done(libxl__egc *egc, libxl__multidev *multidev,
                              int rc)
 {
     EGC_GC;
-    add_pcidevs_state *apds = CONTAINER_OF(multidev, *apds, multidev);
+    add_pcis_state *apds = CONTAINER_OF(multidev, *apds, multidev);
 
     /* Convenience aliases */
     libxl_domain_config *d_config = apds->d_config;
@@ -1779,7 +1779,7 @@ static void add_pcidevs_done(libxl__egc *egc, libxl__multidev *multidev,
 
     if (d_config->num_pcidevs > 0 && !libxl_get_stubdom_id(CTX, domid)) {
         rc = libxl__create_pci_backend(gc, domid, d_config->pcidevs,
-            d_config->num_pcidevs);
+                                       d_config->num_pcidevs);
         if (rc < 0) {
             LOGD(ERROR, domid, "libxl_create_pci_backend failed: %d", rc);
             goto out;
@@ -1792,7 +1792,7 @@ out:
 }
 
 static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
-                                    libxl_device_pci *pcidev, int force)
+                                    libxl_device_pci *pci, int force)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *state;
@@ -1804,12 +1804,12 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
-                     pcidev->bus, pcidev->dev, pcidev->func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
+                     pci->bus, pci->dev, pci->func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
-    if ( !force && (pcidev->vdevfn & 0x7) == 0 ) {
+    if ( !force && (pci->vdevfn & 0x7) == 0 ) {
         libxl__qemu_traditional_cmd(gc, domid, "pci-rem");
         if (libxl__wait_for_device_model_deprecated(gc, domid, "pci-removed",
                                          NULL, NULL, NULL) < 0) {
@@ -1830,7 +1830,7 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
 typedef struct pci_remove_state {
     libxl__ao_device *aodev;
     libxl_domid domid;
-    libxl_device_pci *pcidev;
+    libxl_device_pci *pci;
     bool force;
     bool hvm;
     unsigned int orig_vdev;
@@ -1844,7 +1844,7 @@ typedef struct pci_remove_state {
 } pci_remove_state;
 
 static void libxl__device_pci_remove_common(libxl__egc *egc,
-    uint32_t domid, libxl_device_pci *pcidev, bool force,
+    uint32_t domid, libxl_device_pci *pci, bool force,
     libxl__ao_device *aodev);
 static void device_pci_remove_common_next(libxl__egc *egc,
     pci_remove_state *prs, int rc);
@@ -1869,7 +1869,7 @@ static void pci_remove_done(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 
 static void do_pci_remove(libxl__egc *egc, uint32_t domid,
-                          libxl_device_pci *pcidev, int force,
+                          libxl_device_pci *pci, int force,
                           pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
@@ -1887,8 +1887,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
     libxl__ptr_add(gc, assigned);
 
     rc = ERROR_INVAL;
-    if ( !is_pcidev_in_array(assigned, num, pcidev->domain,
-                      pcidev->bus, pcidev->dev, pcidev->func) ) {
+    if ( !is_pci_in_array(assigned, num, pci->domain,
+                          pci->bus, pci->dev, pci->func) ) {
         LOGD(ERROR, domainid, "PCI device not attached to this domain");
         goto out_fail;
     }
@@ -1917,8 +1917,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
-                                     pcidev->bus, pcidev->dev, pcidev->func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                                     pci->bus, pci->dev, pci->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -1953,8 +1953,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain,
-                               pcidev->bus, pcidev->dev, pcidev->func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                               pci->bus, pci->dev, pci->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1988,7 +1988,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1996,7 +1996,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
     if (rc)
         goto out;
 
-    rc = qemu_pci_remove_xenstore(gc, domid, pcidev, prs->force);
+    rc = qemu_pci_remove_xenstore(gc, domid, pci, prs->force);
 
 out:
     pci_remove_detatched(egc, prs, rc);
@@ -2010,7 +2010,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     int rc;
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     rc = libxl__ev_time_register_rel(ao, &prs->timeout,
                                      pci_remove_timeout,
@@ -2018,7 +2018,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+                           pci->bus, pci->dev, pci->func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2080,14 +2080,14 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl__ao *const ao = prs->aodev->ao;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     if (rc) goto out;
 
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pcidev->bus, pcidev->dev, pcidev->func);
+                         pci->bus, pci->dev, pci->func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2135,10 +2135,10 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     pci_remove_state *prs = CONTAINER_OF(ev, *prs, timeout);
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pcidev->bus, pcidev->dev, pcidev->func);
+         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2156,7 +2156,7 @@ static void pci_remove_detatched(libxl__egc *egc,
     bool isstubdom;
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
     libxl_domid domid = prs->domid;
 
     /* Cleaning QMP states ASAP */
@@ -2170,30 +2170,30 @@ static void pci_remove_detatched(libxl__egc *egc,
     isstubdom = libxl_is_stubdom(CTX, domid, &domainid);
 
     /* don't do multiple resets while some functions are still passed through */
-    if ( (pcidev->vdevfn & 0x7) == 0 ) {
-        libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+    if ((pci->vdevfn & 0x7) == 0) {
+        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid, pcidev_encode_bdf(pcidev));
+        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
 
     stubdomid = libxl_get_stubdom_id(CTX, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pcidev_s;
+        libxl_device_pci *pci_s;
         libxl__ao_device *const stubdom_aodev = &prs->stubdom_aodev;
 
-        GCNEW(pcidev_s);
-        libxl_device_pci_init(pcidev_s);
-        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
+        GCNEW(pci_s);
+        libxl_device_pci_init(pci_s);
+        libxl_device_pci_copy(CTX, pci_s, pci);
 
         libxl__prepare_ao_device(ao, stubdom_aodev);
         stubdom_aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
         stubdom_aodev->callback = pci_remove_stubdom_done;
         stubdom_aodev->update_json = prs->aodev->update_json;
-        libxl__device_pci_remove_common(egc, stubdomid, pcidev_s,
+        libxl__device_pci_remove_common(egc, stubdomid, pci_s,
                                         prs->force, stubdom_aodev);
         return;
     }
@@ -2219,14 +2219,14 @@ static void pci_remove_done(libxl__egc *egc,
 
     if (rc) goto out;
 
-    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pcidev);
+    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pci);
 out:
     device_pci_remove_common_next(egc, prs, rc);
 }
 
 static void libxl__device_pci_remove_common(libxl__egc *egc,
                                             uint32_t domid,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             bool force,
                                             libxl__ao_device *aodev)
 {
@@ -2237,7 +2237,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     GCNEW(prs);
     prs->aodev = aodev;
     prs->domid = domid;
-    prs->pcidev = pcidev;
+    prs->pci = pci;
     prs->force = force;
     libxl__xswait_init(&prs->xswait);
     libxl__ev_qmp_init(&prs->qmp);
@@ -2247,16 +2247,16 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
-    prs->orig_vdev = pcidev->vdevfn & ~7U;
+    prs->orig_vdev = pci->vdevfn & ~7U;
 
-    if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( pci_multifunction_check(gc, pcidev, &prs->pfunc_mask) ) {
+    if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
+        if ( pci_multifunction_check(gc, pci, &prs->pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
-        pcidev->vfunc_mask &= prs->pfunc_mask;
-    }else{
-        prs->pfunc_mask = (1 << pcidev->func);
+        pci->vfunc_mask &= prs->pfunc_mask;
+    } else {
+        prs->pfunc_mask = (1 << pci->func);
     }
 
     rc = 0;
@@ -2273,7 +2273,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
     const unsigned int orig_vdev = prs->orig_vdev;
@@ -2284,13 +2284,13 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         const int i = prs->next_func;
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
-            if ( pcidev->vfunc_mask == pfunc_mask ) {
-                pcidev->func = i;
-                pcidev->vdevfn = orig_vdev | i;
-            }else{
-                pcidev->vdevfn = orig_vdev;
+            if ( pci->vfunc_mask == pfunc_mask ) {
+                pci->func = i;
+                pci->vdevfn = orig_vdev | i;
+            } else {
+                pci->vdevfn = orig_vdev;
             }
-            do_pci_remove(egc, domid, pcidev, prs->force, prs);
+            do_pci_remove(egc, domid, pci, prs->force, prs);
             return;
         }
     }
@@ -2306,7 +2306,7 @@ out:
 }
 
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
-                            libxl_device_pci *pcidev,
+                            libxl_device_pci *pci,
                             const libxl_asyncop_how *ao_how)
 
 {
@@ -2318,12 +2318,12 @@ int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_remove_common(egc, domid, pcidev, false, aodev);
+    libxl__device_pci_remove_common(egc, domid, pci, false, aodev);
     return AO_INPROGRESS;
 }
 
 int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
-                             libxl_device_pci *pcidev,
+                             libxl_device_pci *pci,
                              const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -2334,7 +2334,7 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_remove_common(egc, domid, pcidev, true, aodev);
+    libxl__device_pci_remove_common(egc, domid, pci, true, aodev);
     return AO_INPROGRESS;
 }
 
@@ -2353,7 +2353,7 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
     if (s)
         vdevfn = strtol(s, (char **) NULL, 16);
 
-    pcidev_struct_fill(pci, domain, bus, dev, func, vdevfn);
+    pci_struct_fill(pci, domain, bus, dev, func, vdevfn);
 
     s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/opts-%d", be_path, nr));
     if (s) {
@@ -2398,7 +2398,7 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num
     GC_INIT(ctx);
     char *be_path;
     unsigned int n, i;
-    libxl_device_pci *pcidevs = NULL;
+    libxl_device_pci *pcis = NULL;
 
     *num = 0;
 
@@ -2407,28 +2407,28 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num
     if (libxl__device_pci_get_num(gc, be_path, &n))
         goto out;
 
-    pcidevs = calloc(n, sizeof(libxl_device_pci));
+    pcis = calloc(n, sizeof(libxl_device_pci));
 
     for (i = 0; i < n; i++)
-        libxl__device_pci_from_xs_be(gc, be_path, i, pcidevs + i);
+        libxl__device_pci_from_xs_be(gc, be_path, i, pcis + i);
 
     *num = n;
 out:
     GC_FREE;
-    return pcidevs;
+    return pcis;
 }
 
 void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
                                    libxl__multidev *multidev)
 {
     STATE_AO_GC(multidev->ao);
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_list(CTX, domid, &num);
-    if ( pcidevs == NULL )
+    pcis = libxl_device_pci_list(CTX, domid, &num);
+    if ( pcis == NULL )
         return;
-    libxl__ptr_add(gc, pcidevs);
+    libxl__ptr_add(gc, pcis);
 
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
@@ -2436,7 +2436,7 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
          * devices by the time we even get here!
          */
         libxl__ao_device *aodev = libxl__multidev_prepare(multidev);
-        libxl__device_pci_remove_common(egc, domid, pcidevs + i, true,
+        libxl__device_pci_remove_common(egc, domid, pcis + i, true,
                                         aodev);
     }
 }
@@ -2452,10 +2452,10 @@ int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid,
     for (i = 0 ; i < d_config->num_pcidevs ; i++) {
         uint64_t vga_iomem_start = 0xa0000 >> XC_PAGE_SHIFT;
         uint32_t stubdom_domid;
-        libxl_device_pci *pcidev = &d_config->pcidevs[i];
+        libxl_device_pci *pci = &d_config->pcidevs[i];
         unsigned long pci_device_class;
 
-        if (sysfs_dev_get_class(gc, pcidev, &pci_device_class))
+        if (sysfs_dev_get_class(gc, pci, &pci_device_class))
             continue;
         if (pci_device_class != 0x030000) /* VGA class */
             continue;
@@ -2494,7 +2494,7 @@ static int libxl_device_pci_compare(const libxl_device_pci *d1,
 
 #define libxl__device_pci_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT_X(pcidev, pci, PCI,
+DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .get_num = libxl__device_pci_get_num,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
diff --git a/tools/libs/light/libxl_pvcalls.c b/tools/libs/light/libxl_pvcalls.c
index 870318e716..1fbedf651c 100644
--- a/tools/libs/light/libxl_pvcalls.c
+++ b/tools/libs/light/libxl_pvcalls.c
@@ -34,4 +34,4 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(pvcallsif)
 
 LIBXL_DEFINE_DEVICE_REMOVE(pvcallsif)
 
-DEFINE_DEVICE_TYPE_STRUCT(pvcallsif, PVCALLS);
+DEFINE_DEVICE_TYPE_STRUCT(pvcallsif, PVCALLS, pvcallsifs);
diff --git a/tools/libs/light/libxl_usb.c b/tools/libs/light/libxl_usb.c
index 171bb04439..c5ae59681c 100644
--- a/tools/libs/light/libxl_usb.c
+++ b/tools/libs/light/libxl_usb.c
@@ -2139,7 +2139,7 @@ void libxl_device_usbdev_list_free(libxl_device_usbdev *list, int nr)
 
 LIBXL_DEFINE_DEVID_TO_DEVICE(usbctrl)
 LIBXL_DEFINE_DEVICE_LIST(usbctrl)
-DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB,
+DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB, usbctrls,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__usbctrl_from_xenstore,
     .dm_needed = libxl_device_usbctrl_dm_needed
 );
@@ -2147,7 +2147,7 @@ DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB,
 #define libxl__device_from_usbdev NULL
 #define libxl__device_usbdev_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT(usbdev, VUSB);
+DEFINE_DEVICE_TYPE_STRUCT(usbdev, VUSB, usbdevs);
 
 /*
  * Local variables:
diff --git a/tools/libs/light/libxl_vdispl.c b/tools/libs/light/libxl_vdispl.c
index 8ddc8940e9..60427c76c2 100644
--- a/tools/libs/light/libxl_vdispl.c
+++ b/tools/libs/light/libxl_vdispl.c
@@ -206,7 +206,7 @@ LIBXL_DEFINE_DEVICE_ADD(vdispl)
 LIBXL_DEFINE_DEVICE_REMOVE(vdispl)
 LIBXL_DEFINE_DEVICE_LIST(vdispl)
 
-DEFINE_DEVICE_TYPE_STRUCT(vdispl, VDISPL,
+DEFINE_DEVICE_TYPE_STRUCT(vdispl, VDISPL, vdispls,
     .update_config = (device_update_config_fn_t)libxl__update_config_vdispl,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__vdispl_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vkb.c b/tools/libs/light/libxl_vkb.c
index 4c44a813c1..bb88059f93 100644
--- a/tools/libs/light/libxl_vkb.c
+++ b/tools/libs/light/libxl_vkb.c
@@ -336,7 +336,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(vkb)
 LIBXL_DEFINE_DEVICE_LIST(vkb)
 LIBXL_DEFINE_DEVICE_REMOVE(vkb)
 
-DEFINE_DEVICE_TYPE_STRUCT(vkb, VKBD,
+DEFINE_DEVICE_TYPE_STRUCT(vkb, VKBD, vkbs,
     .skip_attach = 1,
     .dm_needed = libxl__device_vkb_dm_needed,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vsnd.c b/tools/libs/light/libxl_vsnd.c
index 0bc5f6dbb1..bb7942bbc9 100644
--- a/tools/libs/light/libxl_vsnd.c
+++ b/tools/libs/light/libxl_vsnd.c
@@ -670,7 +670,7 @@ LIBXL_DEFINE_DEVICE_ADD(vsnd)
 LIBXL_DEFINE_DEVICE_REMOVE(vsnd)
 LIBXL_DEFINE_DEVICE_LIST(vsnd)
 
-DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND,
+DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND, vsnds,
     .update_config = (device_update_config_fn_t) libxl__update_config_vsnd,
     .from_xenstore = (device_from_xenstore_fn_t) libxl__vsnd_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vtpm.c b/tools/libs/light/libxl_vtpm.c
index dd00b267bb..0148c572d4 100644
--- a/tools/libs/light/libxl_vtpm.c
+++ b/tools/libs/light/libxl_vtpm.c
@@ -231,7 +231,7 @@ LIBXL_DEFINE_DEVICE_ADD(vtpm)
 LIBXL_DEFINE_DEVICE_REMOVE(vtpm)
 LIBXL_DEFINE_DEVICE_LIST(vtpm)
 
-DEFINE_DEVICE_TYPE_STRUCT(vtpm, VTPM,
+DEFINE_DEVICE_TYPE_STRUCT(vtpm, VTPM, vtpms,
     .update_config = libxl_device_vtpm_update_config,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__vtpm_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 12fc0b3a7f..1d38fffce3 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -23,15 +23,15 @@ static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
     return 0;
 }
 
-static int pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func, unsigned int vdevfn)
+static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                           unsigned int bus, unsigned int dev,
+                           unsigned int func, unsigned int vdevfn)
 {
-    pcidev->domain = domain;
-    pcidev->bus = bus;
-    pcidev->dev = dev;
-    pcidev->func = func;
-    pcidev->vdevfn = vdevfn;
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
     return 0;
 }
 
@@ -47,7 +47,7 @@ static int pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
 #define STATE_RDM_STRATEGY      10
 #define STATE_RESERVE_POLICY    11
 #define INVALID         0xffffffff
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str)
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
 {
     unsigned state = STATE_DOMAIN;
     unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
@@ -110,11 +110,11 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
                 }
                 *ptr = '\0';
                 if ( !strcmp(tok, "*") ) {
-                    pcidev->vfunc_mask = LIBXL_PCI_FUNC_ALL;
+                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
                 }else{
                     if ( hex_convert(tok, &func, 0x7) )
                         goto parse_error;
-                    pcidev->vfunc_mask = (1 << 0);
+                    pci->vfunc_mask = (1 << 0);
                 }
                 tok = ptr + 1;
             }
@@ -141,18 +141,18 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
                 state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
                 *ptr = '\0';
                 if ( !strcmp(optkey, "msitranslate") ) {
-                    pcidev->msitranslate = atoi(tok);
+                    pci->msitranslate = atoi(tok);
                 }else if ( !strcmp(optkey, "power_mgmt") ) {
-                    pcidev->power_mgmt = atoi(tok);
+                    pci->power_mgmt = atoi(tok);
                 }else if ( !strcmp(optkey, "permissive") ) {
-                    pcidev->permissive = atoi(tok);
+                    pci->permissive = atoi(tok);
                 }else if ( !strcmp(optkey, "seize") ) {
-                    pcidev->seize = atoi(tok);
+                    pci->seize = atoi(tok);
                 } else if (!strcmp(optkey, "rdm_policy")) {
                     if (!strcmp(tok, "strict")) {
-                        pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
                     } else if (!strcmp(tok, "relaxed")) {
-                        pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
                     } else {
                         XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
                                           " policy: 'strict' or 'relaxed'.",
@@ -175,7 +175,7 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
     assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
 
     /* Just a pretty way to fill in the values */
-    pcidev_struct_fill(pcidev, dom, bus, dev, func, vslot << 3);
+    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
 
     free(buf2);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54505.94740 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGb-0005gW-S0; Tue, 15 Dec 2020 16:33:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54505.94740; Tue, 15 Dec 2020 16:33:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGb-0005gO-Od; Tue, 15 Dec 2020 16:33:37 +0000
Received: by outflank-mailman (input) for mailman id 54505;
 Tue, 15 Dec 2020 16:33:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGa-0005gF-ED
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGa-0002q9-D3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGa-0005GQ-Bu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=iIDiQy2i9j/Q027JgZPAMcztF6vWex7Q4OPUfsDFCp0=; b=wOv7cnrNre13RKdiyN1jL4Um7A
	mSRx98EucHSkFY3XVYSja8DeXQydW0yMeJLPfyQYtKG3Nyc2CM454Id9ng7GWT2j02iUNeBtXaDrU
	I/dCcYrX/kto8cycnB5GumdrMXd7R/ms+XkCGMINEFr7/Pl1TjAevko+vG2nCigCV85U=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xl: s/pcidev/pci where possible
Message-Id: <E1kpDGa-0005GQ-Bu@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:36 +0000

commit 6c2590967fec90ec024a3608989b0796a043becf
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:10 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:20 2020 +0000

    xl: s/pcidev/pci where possible
    
    To improve naming consistency, replaces occurrences of 'pcidev' with 'pci'.
    The only remaining use of the term should be in relation to
    'libxl_domain_config' where there are fields named 'pcidevs' and 'num_pcidevs'.
    
    Purely cosmetic. No functional change.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xl/xl_parse.c | 22 ++++++++---------
 tools/xl/xl_pci.c   | 68 ++++++++++++++++++++++++++---------------------------
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index cae8eb679c..4ebf39620a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1473,21 +1473,21 @@ void parse_config_data(const char *config_source,
         d_config->num_pcidevs = 0;
         d_config->pcidevs = NULL;
         for(i = 0; (buf = xlu_cfg_get_listitem (pcis, i)) != NULL; i++) {
-            libxl_device_pci *pcidev;
-
-            pcidev = ARRAY_EXTEND_INIT_NODEVID(d_config->pcidevs,
-                                               d_config->num_pcidevs,
-                                               libxl_device_pci_init);
-            pcidev->msitranslate = pci_msitranslate;
-            pcidev->power_mgmt = pci_power_mgmt;
-            pcidev->permissive = pci_permissive;
-            pcidev->seize = pci_seize;
+            libxl_device_pci *pci;
+
+            pci = ARRAY_EXTEND_INIT_NODEVID(d_config->pcidevs,
+                                            d_config->num_pcidevs,
+                                            libxl_device_pci_init);
+            pci->msitranslate = pci_msitranslate;
+            pci->power_mgmt = pci_power_mgmt;
+            pci->permissive = pci_permissive;
+            pci->seize = pci_seize;
             /*
              * Like other pci option, the per-device policy always follows
              * the global policy by default.
              */
-            pcidev->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_bdf(config, pcidev, buf);
+            pci->rdm_policy = b_info->u.hvm.rdm.policy;
+            e = xlu_pci_parse_bdf(config, pci, buf);
             if (e) {
                 fprintf(stderr,
                         "unable to parse PCI BDF `%s' for passthrough\n",
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 58345bdae2..34fcf5a4fa 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -24,20 +24,20 @@
 
 static void pcilist(uint32_t domid)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_list(ctx, domid, &num);
-    if (pcidevs == NULL)
+    pcis = libxl_device_pci_list(ctx, domid, &num);
+    if (pcis == NULL)
         return;
     printf("Vdev Device\n");
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
-               (pcidevs[i].vdevfn >> 3) & 0x1f, pcidevs[i].vdevfn & 0x7,
-               pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
-        libxl_device_pci_dispose(&pcidevs[i]);
+               (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcidevs);
+    free(pcis);
 }
 
 int main_pcilist(int argc, char **argv)
@@ -57,28 +57,28 @@ int main_pcilist(int argc, char **argv)
 
 static int pcidetach(uint32_t domid, const char *bdf, int force)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
     if (force) {
-        if (libxl_device_pci_destroy(ctx, domid, &pcidev, 0))
+        if (libxl_device_pci_destroy(ctx, domid, &pci, 0))
             r = 1;
     } else {
-        if (libxl_device_pci_remove(ctx, domid, &pcidev, 0))
+        if (libxl_device_pci_remove(ctx, domid, &pci, 0))
             r = 1;
     }
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -108,24 +108,24 @@ int main_pcidetach(int argc, char **argv)
 
 static int pciattach(uint32_t domid, const char *bdf, const char *vs)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_add(ctx, domid, &pcidev, 0))
+    if (libxl_device_pci_add(ctx, domid, &pci, 0))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -155,19 +155,19 @@ int main_pciattach(int argc, char **argv)
 
 static void pciassignable_list(void)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
 
-    if ( pcidevs == NULL )
+    if ( pcis == NULL )
         return;
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
-               pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
-        libxl_device_pci_dispose(&pcidevs[i]);
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcidevs);
+    free(pcis);
 }
 
 int main_pciassignable_list(int argc, char **argv)
@@ -184,24 +184,24 @@ int main_pciassignable_list(int argc, char **argv)
 
 static int pciassignable_add(const char *bdf, int rebind)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_add(ctx, &pcidev, rebind))
+    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -226,24 +226,24 @@ int main_pciassignable_add(int argc, char **argv)
 
 static int pciassignable_remove(const char *bdf, int rebind)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_remove(ctx, &pcidev, rebind))
+    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54506.94744 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGl-0005i2-TL; Tue, 15 Dec 2020 16:33:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54506.94744; Tue, 15 Dec 2020 16:33:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGl-0005hu-QF; Tue, 15 Dec 2020 16:33:47 +0000
Received: by outflank-mailman (input) for mailman id 54506;
 Tue, 15 Dec 2020 16:33:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGk-0005hm-Hc
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGk-0002qT-Gt
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGk-0005HD-Fv
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PMU5xv4JhM2Kq4Ia5V8rQZ2E54xXpkNU1cwb6/gZN3c=; b=xBXe2JmZp/YKNXi01Tjnxqzp1Q
	ykDQl+NMATesZgaJqCXPCYMnGpMQgdDXi0CnqWMmqI9TmoWjUFcDpGQ73lZmx9LZ4+j0ntCDIhgPt
	Ejju4Bm0hu43SLHjh9b8NiMzMMlXg2hV4VNoP3gIr3j475KWLCtNDfgASjeEhG5s2Xo0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: make libxl__device_list() work correctly for LIBXL__DEVICE_KIND_PCI...
Message-Id: <E1kpDGk-0005HD-Fv@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:46 +0000

commit fce69998edd7583417c833fe1bf3347efcdc93e7
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:11 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: make libxl__device_list() work correctly for LIBXL__DEVICE_KIND_PCI...
    
    ... devices.
    
    Currently there is an assumption built into libxl__device_list() that device
    backends are fully enumarated under the '/libxl' path in xenstore. This is
    not the case for PCI backend devices, which are only properly enumerated
    under '/local/domain/0/backend'.
    
    This patch adds a new get_path() method to libxl__device_type to allow a
    backend implementation (such as PCI) to specify the xenstore path where
    devices are enumerated and modifies libxl__device_list() to use this method
    if it is available. Also, if the get_num() method is defined then the
    from_xenstore() method expects to be passed the backend path without the device
    number concatenated, so this issue is also rectified.
    
    Having made libxl__device_list() work correctly, this patch removes the
    open-coded libxl_pci_device_pci_list() in favour of an evaluation of the
    LIBXL_DEFINE_DEVICE_LIST() macro. This has the side-effect of also defining
    libxl_pci_device_pci_list_free() which will be used in subsequent patches.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h             |  7 +++++
 tools/libs/light/libxl_device.c   | 66 +++++++++++++++++++++------------------
 tools/libs/light/libxl_internal.h |  2 ++
 tools/libs/light/libxl_pci.c      | 29 +++++------------
 4 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 733263522b..bb7fc893fc 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -451,6 +451,12 @@
  */
 #define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_LIST_FREE indicates that the
+ * libxl_device_pci_list_free() function is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_LIST_FREE 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2321,6 +2327,7 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
 
 libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid,
                                         int *num);
+void libxl_device_pci_list_free(libxl_device_pci* list, int num);
 
 /*
  * Turns the current process into a backend device service daemon
diff --git a/tools/libs/light/libxl_device.c b/tools/libs/light/libxl_device.c
index e081faf9a9..ac173a043d 100644
--- a/tools/libs/light/libxl_device.c
+++ b/tools/libs/light/libxl_device.c
@@ -2011,7 +2011,7 @@ void *libxl__device_list(libxl__gc *gc, const libxl__device_type *dt,
     void *r = NULL;
     void *list = NULL;
     void *item = NULL;
-    char *libxl_path;
+    char *path;
     char **dir = NULL;
     unsigned int ndirs = 0;
     unsigned int ndevs = 0;
@@ -2019,42 +2019,46 @@ void *libxl__device_list(libxl__gc *gc, const libxl__device_type *dt,
 
     *num = 0;
 
-    libxl_path = GCSPRINTF("%s/device/%s",
-                           libxl__xs_libxl_path(gc, domid),
-                           libxl__device_kind_to_string(dt->type));
-
-    dir = libxl__xs_directory(gc, XBT_NULL, libxl_path, &ndirs);
+    if (dt->get_path) {
+        rc = dt->get_path(gc, domid, &path);
+        if (rc) goto out;
+    } else {
+        path = GCSPRINTF("%s/device/%s",
+                         libxl__xs_libxl_path(gc, domid),
+                         libxl__device_kind_to_string(dt->type));
+    }
 
-    if (dir && ndirs) {
-        if (dt->get_num) {
-            if (ndirs != 1) {
-                LOGD(ERROR, domid, "multiple entries in %s\n", libxl_path);
-                rc = ERROR_FAIL;
-                goto out;
-            }
-            rc = dt->get_num(gc, GCSPRINTF("%s/%s", libxl_path, *dir), &ndevs);
-            if (rc) goto out;
-        } else {
+    if (dt->get_num) {
+        rc = dt->get_num(gc, path, &ndevs);
+        if (rc) goto out;
+    } else {
+        dir = libxl__xs_directory(gc, XBT_NULL, path, &ndirs);
+        if (dir && ndirs)
             ndevs = ndirs;
-        }
-        list = libxl__malloc(NOGC, dt->dev_elem_size * ndevs);
-        item = list;
+    }
 
-        while (*num < ndevs) {
-            dt->init(item);
+    if (!ndevs)
+        return NULL;
 
-            if (dt->from_xenstore) {
-                int nr = dt->get_num ? *num : atoi(*dir);
-                char *device_libxl_path = GCSPRINTF("%s/%s", libxl_path, *dir);
-                rc = dt->from_xenstore(gc, device_libxl_path, nr, item);
-                if (rc) goto out;
-            }
+    list = libxl__malloc(NOGC, dt->dev_elem_size * ndevs);
+    item = list;
 
-            item = (uint8_t *)item + dt->dev_elem_size;
-            ++(*num);
-            if (!dt->get_num)
-                ++dir;
+    while (*num < ndevs) {
+        dt->init(item);
+
+        if (dt->from_xenstore) {
+            int nr = dt->get_num ? *num : atoi(*dir);
+            char *device_path = dt->get_num ? path :
+                GCSPRINTF("%s/%d", path, nr);
+
+            rc = dt->from_xenstore(gc, device_path, nr, item);
+            if (rc) goto out;
         }
+
+        item = (uint8_t *)item + dt->dev_elem_size;
+        ++(*num);
+        if (!dt->get_num)
+            ++dir;
     }
 
     r = list;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index c2c5a9b926..d0c23def3c 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -3917,6 +3917,7 @@ typedef int (*device_dm_needed_fn_t)(void *, unsigned);
 typedef void (*device_update_config_fn_t)(libxl__gc *, void *, void *);
 typedef int (*device_update_devid_fn_t)(libxl__gc *, uint32_t, void *);
 typedef int (*device_get_num_fn_t)(libxl__gc *, const char *, unsigned int *);
+typedef int (*device_get_path_fn_t)(libxl__gc *, uint32_t, char **);
 typedef int (*device_from_xenstore_fn_t)(libxl__gc *, const char *,
                                          libxl_devid, void *);
 typedef int (*device_set_xenstore_config_fn_t)(libxl__gc *, uint32_t, void *,
@@ -3941,6 +3942,7 @@ struct libxl__device_type {
     device_update_config_fn_t       update_config;
     device_update_devid_fn_t        update_devid;
     device_get_num_fn_t             get_num;
+    device_get_path_fn_t            get_path;
     device_from_xenstore_fn_t       from_xenstore;
     device_set_xenstore_config_fn_t set_xenstore_config;
 };
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 3340076d2c..d536702ac4 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -2393,29 +2393,13 @@ static int libxl__device_pci_get_num(libxl__gc *gc, const char *be_path,
     return rc;
 }
 
-libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num)
+static int libxl__device_pci_get_path(libxl__gc *gc, uint32_t domid,
+                                      char **path)
 {
-    GC_INIT(ctx);
-    char *be_path;
-    unsigned int n, i;
-    libxl_device_pci *pcis = NULL;
-
-    *num = 0;
-
-    be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
-                                                LIBXL__DEVICE_KIND_PCI);
-    if (libxl__device_pci_get_num(gc, be_path, &n))
-        goto out;
+    *path = libxl__domain_device_backend_path(gc, 0, domid, 0,
+                                              LIBXL__DEVICE_KIND_PCI);
 
-    pcis = calloc(n, sizeof(libxl_device_pci));
-
-    for (i = 0; i < n; i++)
-        libxl__device_pci_from_xs_be(gc, be_path, i, pcis + i);
-
-    *num = n;
-out:
-    GC_FREE;
-    return pcis;
+    return 0;
 }
 
 void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
@@ -2492,10 +2476,13 @@ static int libxl_device_pci_compare(const libxl_device_pci *d1,
     return COMPARE_PCI(d1, d2);
 }
 
+LIBXL_DEFINE_DEVICE_LIST(pci)
+
 #define libxl__device_pci_update_devid NULL
 
 DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .get_num = libxl__device_pci_get_num,
+    .get_path = libxl__device_pci_get_path,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:33:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:33:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54507.94748 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGv-0005jM-Us; Tue, 15 Dec 2020 16:33:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54507.94748; Tue, 15 Dec 2020 16:33:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDGv-0005jG-Rl; Tue, 15 Dec 2020 16:33:57 +0000
Received: by outflank-mailman (input) for mailman id 54507;
 Tue, 15 Dec 2020 16:33:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGu-0005j6-Kq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGu-0002qg-KB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDGu-0005I7-JC
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:33:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ZcdDO8uuZBHgfFIYJtgDNYkaFNfqPbhw99fUBfM9OWU=; b=KliMo0RdGwSltPIvuE+iHM42Tq
	304MtrsLa3Nkh5dQGIzLUktZd4fLw1sNkGDeKd26mEfL/Wojrgywm4BUqqRWgD1k2tc1QJfidjLEf
	wefIW6y6LZtoJL7jqNNl5t9ovfSnLhcnWrXctT4Ta7jPdxX2RdXE+uZ/8RTX6nVJdgK8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: Make sure devices added by pci-attach are reflected in the config
Message-Id: <E1kpDGu-0005I7-JC@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:33:56 +0000

commit 0fdb48ffe7a1a56745b999506bf572e260e8ae0a
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:12 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: Make sure devices added by pci-attach are reflected in the config
    
    Currently libxl__device_pci_add_xenstore() is broken in that does not
    update the domain's configuration for the first device added (which causes
    creation of the overall backend area in xenstore). This can be easily observed
    by running 'xl list -l' after adding a single device: the device will be
    missing.
    
    This patch fixes the problem and adds a DEBUG log line to allow easy
    verification that the domain configuration is being modified. Also, the use
    of libxl__device_generic_add() is dropped as it leads to a confusing situation
    where only partial backend information is written under the xenstore
    '/libxl' path. For LIBXL__DEVICE_KIND_PCI devices the only definitive
    information in xenstore is under '/local/domain/0/backend' (the '0' being
    hard-coded).
    
    NOTE: This patch includes a whitespace in add_pcis_done().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 87 +++++++++++++++++++++++---------------------
 1 file changed, 45 insertions(+), 42 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index d536702ac4..3f85f0d762 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -79,39 +79,55 @@ static void libxl__device_from_pci(libxl__gc *gc, uint32_t domid,
     device->kind = LIBXL__DEVICE_KIND_PCI;
 }
 
-static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
-                                     const libxl_device_pci *pci,
-                                     int num)
+static void libxl__create_pci_backend(libxl__gc *gc, xs_transaction_t t,
+                                      uint32_t domid, const libxl_device_pci *pci)
 {
-    flexarray_t *front = NULL;
-    flexarray_t *back = NULL;
-    libxl__device device;
-    int i;
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    flexarray_t *front, *back;
+    char *fe_path, *be_path;
+    struct xs_permissions fe_perms[2], be_perms[2];
+
+    LOGD(DEBUG, domid, "Creating pci backend");
 
     front = flexarray_make(gc, 16, 1);
     back = flexarray_make(gc, 16, 1);
 
-    LOGD(DEBUG, domid, "Creating pci backend");
-
-    /* add pci device */
-    libxl__device_from_pci(gc, domid, pci, &device);
+    fe_path = libxl__domain_device_frontend_path(gc, domid, 0,
+                                                 LIBXL__DEVICE_KIND_PCI);
+    be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
+                                                LIBXL__DEVICE_KIND_PCI);
 
+    flexarray_append_pair(back, "frontend", fe_path);
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
-    flexarray_append_pair(back, "online", "1");
+    flexarray_append_pair(back, "online", GCSPRINTF("%d", 1));
     flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateInitialising));
     flexarray_append_pair(back, "domain", libxl__domid_to_name(gc, domid));
 
-    for (i = 0; i < num; i++, pci++)
-        libxl_create_pci_backend_device(gc, back, i, pci);
+    be_perms[0].id = 0;
+    be_perms[0].perms = XS_PERM_NONE;
+    be_perms[1].id = domid;
+    be_perms[1].perms = XS_PERM_READ;
+
+    xs_rm(ctx->xsh, t, be_path);
+    xs_mkdir(ctx->xsh, t, be_path);
+    xs_set_permissions(ctx->xsh, t, be_path, be_perms,
+                       ARRAY_SIZE(be_perms));
+    libxl__xs_writev(gc, t, be_path, libxl__xs_kvs_of_flexarray(gc, back));
 
-    flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num));
+    flexarray_append_pair(front, "backend", be_path);
     flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", 0));
     flexarray_append_pair(front, "state", GCSPRINTF("%d", XenbusStateInitialising));
 
-    return libxl__device_generic_add(gc, XBT_NULL, &device,
-                                     libxl__xs_kvs_of_flexarray(gc, back),
-                                     libxl__xs_kvs_of_flexarray(gc, front),
-                                     NULL);
+    fe_perms[0].id = domid;
+    fe_perms[0].perms = XS_PERM_NONE;
+    fe_perms[1].id = 0;
+    fe_perms[1].perms = XS_PERM_READ;
+
+    xs_rm(ctx->xsh, t, fe_path);
+    xs_mkdir(ctx->xsh, t, fe_path);
+    xs_set_permissions(ctx->xsh, t, fe_path,
+                       fe_perms, ARRAY_SIZE(fe_perms));
+    libxl__xs_writev(gc, t, fe_path, libxl__xs_kvs_of_flexarray(gc, front));
 }
 
 static int libxl__device_pci_add_xenstore(libxl__gc *gc,
@@ -135,8 +151,6 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
     be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
                                                 LIBXL__DEVICE_KIND_PCI);
     num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
-    if (!num_devs)
-        return libxl__create_pci_backend(gc, domid, pci, 1);
 
     libxl_domain_type domtype = libxl__domain_type(gc, domid);
     if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
@@ -150,17 +164,17 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
     back = flexarray_make(gc, 16, 1);
 
     LOGD(DEBUG, domid, "Adding new pci device to xenstore");
-    num = atoi(num_devs);
+    num = num_devs ? atoi(num_devs) : 0;
     libxl_create_pci_backend_device(gc, back, num, pci);
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num + 1));
-    if (!starting)
+    if (num && !starting)
         flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateReconfiguring));
 
     /*
      * Stubdomin config is derived from its target domain, it doesn't have
      * its own file.
      */
-    if (!is_stubdomain) {
+    if (!is_stubdomain && !starting) {
         lock = libxl__lock_domain_userdata(gc, domid);
         if (!lock) {
             rc = ERROR_LOCK_FAIL;
@@ -170,6 +184,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
         rc = libxl__get_domain_configuration(gc, domid, &d_config);
         if (rc) goto out;
 
+        LOGD(DEBUG, domid, "Adding new pci device to config");
         device_add_domain_config(gc, &d_config, &libxl__pci_devtype,
                                  pci);
 
@@ -186,6 +201,10 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
             if (rc) goto out;
         }
 
+        /* This is the first device, so create the backend */
+        if (!num_devs)
+            libxl__create_pci_backend(gc, t, domid, pci);
+
         libxl__xs_writev(gc, t, be_path, libxl__xs_kvs_of_flexarray(gc, back));
 
         rc = libxl__xs_transaction_commit(gc, &t);
@@ -1437,7 +1456,7 @@ out_no_irq:
         }
     }
 
-    if (!starting && !libxl_get_stubdom_id(CTX, domid))
+    if (!libxl_get_stubdom_id(CTX, domid))
         rc = libxl__device_pci_add_xenstore(gc, domid, pci, starting);
     else
         rc = 0;
@@ -1765,28 +1784,12 @@ static void libxl__add_pcis(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
 }
 
 static void add_pcis_done(libxl__egc *egc, libxl__multidev *multidev,
-                             int rc)
+                          int rc)
 {
     EGC_GC;
     add_pcis_state *apds = CONTAINER_OF(multidev, *apds, multidev);
-
-    /* Convenience aliases */
-    libxl_domain_config *d_config = apds->d_config;
-    libxl_domid domid = apds->domid;
     libxl__ao_device *aodev = apds->outer_aodev;
 
-    if (rc) goto out;
-
-    if (d_config->num_pcidevs > 0 && !libxl_get_stubdom_id(CTX, domid)) {
-        rc = libxl__create_pci_backend(gc, domid, d_config->pcidevs,
-                                       d_config->num_pcidevs);
-        if (rc < 0) {
-            LOGD(ERROR, domid, "libxl_create_pci_backend failed: %d", rc);
-            goto out;
-        }
-    }
-
-out:
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54508.94752 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDH6-0005l3-1Q; Tue, 15 Dec 2020 16:34:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54508.94752; Tue, 15 Dec 2020 16:34:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDH5-0005kw-Un; Tue, 15 Dec 2020 16:34:07 +0000
Received: by outflank-mailman (input) for mailman id 54508;
 Tue, 15 Dec 2020 16:34:06 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDH4-0005km-P5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:06 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDH4-0002r5-OR
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:06 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDH4-0005JD-Ma
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:06 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2Sw7QqXT04RcixOLmFJpIkUfgrCMf7kWtMAUcs6JhVc=; b=SV8r0Wfslm3ONgqzZLZVzhvmHG
	sGhEIpiOlGAU+8gyTJR0ZAOXC4rITgjfuVY5P+PyJKY2bH66sVkmoXZhMD7K2FPEmobJMDUmNB+dH
	xmPN0UP6X2/MTmE7N+V1tqvyF0zIWpdRX2k+q/vZEWRh4FFgZqBrnZJswFCOmvfG3nCs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: add/recover 'rdm_policy' to/from PCI backend in xenstore
Message-Id: <E1kpDH4-0005JD-Ma@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:06 +0000

commit d8cba539f2d94385fd2d52483d3efec72b080811
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:13 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: add/recover 'rdm_policy' to/from PCI backend in xenstore
    
    Other parameters, such as 'msitranslate' and 'permissive' are dealt with
    but 'rdm_policy' appears to be have been completely missed.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 3f85f0d762..2a5a4db976 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -61,9 +61,9 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
     flexarray_append(back,
-              GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d",
-                             pci->msitranslate, pci->power_mgmt,
-                             pci->permissive));
+              GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d,rdm_policy=%s",
+                        pci->msitranslate, pci->power_mgmt,
+                        pci->permissive, libxl_rdm_reserve_policy_to_string(pci->rdm_policy)));
     flexarray_append_pair(back, GCSPRINTF("state-%d", num), GCSPRINTF("%d", XenbusStateInitialising));
 }
 
@@ -2374,6 +2374,9 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
             } else if (!strcmp(p, "permissive")) {
                 p = strtok_r(NULL, ",=", &saveptr);
                 pci->permissive = atoi(p);
+            } else if (!strcmp(p, "rdm_policy")) {
+                p = strtok_r(NULL, ",=", &saveptr);
+                libxl_rdm_reserve_policy_from_string(p, &pci->rdm_policy);
             }
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54509.94756 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHG-0005mP-3G; Tue, 15 Dec 2020 16:34:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54509.94756; Tue, 15 Dec 2020 16:34:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHG-0005mI-0K; Tue, 15 Dec 2020 16:34:18 +0000
Received: by outflank-mailman (input) for mailman id 54509;
 Tue, 15 Dec 2020 16:34:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHE-0005m6-SD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHE-0002rH-RS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:16 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHE-0005KU-Qd
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:16 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=d/3Kz+sTIL54B90asW/F82IE3Wh9bqOWuMj6WKvuqhA=; b=aDTRAs79BcuELKXuMx67vixkND
	4ozhDBTJ0v8ek54hhSSSIBwf7Uqec9CTTl465jzIirf+COUaiITBR6RB7mGIS4mzXuVi5DXQqXFYc
	u8dHFiW1uPWyBg0hXrSzZgEeorzmzodNqrq5kUsILxlC8qrs+V5fNIs8fKXwmWcE4M7s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: s/detatched/detached in libxl_pci.c
Message-Id: <E1kpDHE-0005KU-Qd@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:16 +0000

commit 33e1c5a5a8953993ae0b2f28825058b539c05831
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:14 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: s/detatched/detached in libxl_pci.c
    
    Simply spelling correction. Purely cosmetic fix.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 2a5a4db976..b6d3bd29b7 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1864,7 +1864,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
 static void pci_remove_timeout(libxl__egc *egc,
     libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
-static void pci_remove_detatched(libxl__egc *egc,
+static void pci_remove_detached(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 static void pci_remove_stubdom_done(libxl__egc *egc,
     libxl__ao_device *aodev);
@@ -1978,7 +1978,7 @@ skip1:
 skip_irq:
     rc = 0;
 out_fail:
-    pci_remove_detatched(egc, prs, rc); /* must be last */
+    pci_remove_detached(egc, prs, rc); /* must be last */
 }
 
 static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
@@ -2002,7 +2002,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
     rc = qemu_pci_remove_xenstore(gc, domid, pci, prs->force);
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_device_del(libxl__egc *egc,
@@ -2028,7 +2028,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
@@ -2051,7 +2051,7 @@ static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc, libxl__ev_time *ev,
@@ -2067,7 +2067,7 @@ static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc, libxl__ev_time *ev,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_query_cb(libxl__egc *egc,
@@ -2127,7 +2127,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     }
 
 out:
-    pci_remove_detatched(egc, prs, rc); /* must be last */
+    pci_remove_detached(egc, prs, rc); /* must be last */
 }
 
 static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
@@ -2146,12 +2146,12 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
      * error */
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
-static void pci_remove_detatched(libxl__egc *egc,
-                                 pci_remove_state *prs,
-                                 int rc)
+static void pci_remove_detached(libxl__egc *egc,
+                                pci_remove_state *prs,
+                                int rc)
 {
     STATE_AO_GC(prs->aodev->ao);
     int stubdomid = 0;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54510.94760 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHQ-0005o6-4u; Tue, 15 Dec 2020 16:34:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54510.94760; Tue, 15 Dec 2020 16:34:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHQ-0005ny-1p; Tue, 15 Dec 2020 16:34:28 +0000
Received: by outflank-mailman (input) for mailman id 54510;
 Tue, 15 Dec 2020 16:34:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHP-0005np-09
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHO-0002rP-Vg
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHO-0005MR-Tr
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cT809aaaYzOAF8mMJbpjcy8i7iRAelRArUWf3mF+Cmo=; b=KvGuGPeNLN5CmUR1pKqotFz9ak
	iUwHlnfYPMt/Y5Vit3o/VVPr4sCSZMut5sz4LZo02WNMBHPw2BL0cyJSYniKHQ9KhqerjAA6Kjl2j
	9VG4DwRsDgQk+TNOGaMpp9+cG7m+ylarW4+TUpLbzllfUzkU0pse3k9JrIAR9nDHsoPA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: remove extraneous arguments to do_pci_remove() in libxl_pci.c
Message-Id: <E1kpDHO-0005MR-Tr@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:26 +0000

commit a825ab3a6b16d216660e689b082e979dd991ca95
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:15 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove extraneous arguments to do_pci_remove() in libxl_pci.c
    
    Both 'domid' and 'pci' are available in 'pci_remove_state' so there is no
    need to also pass them as separate arguments.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index b6d3bd29b7..bcc4d2ef96 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1871,14 +1871,14 @@ static void pci_remove_stubdom_done(libxl__egc *egc,
 static void pci_remove_done(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 
-static void do_pci_remove(libxl__egc *egc, uint32_t domid,
-                          libxl_device_pci *pci, int force,
-                          pci_remove_state *prs)
+static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *assigned;
+    uint32_t domid = prs->domid;
     libxl_domain_type type = libxl__domain_type(gc, domid);
+    libxl_device_pci *pci = prs->pci;
     int rc, num;
     uint32_t domainid = domid;
 
@@ -2275,7 +2275,6 @@ static void device_pci_remove_common_next(libxl__egc *egc,
     EGC_GC;
 
     /* Convenience aliases */
-    libxl_domid domid = prs->domid;
     libxl_device_pci *const pci = prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
@@ -2293,7 +2292,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
             } else {
                 pci->vdevfn = orig_vdev;
             }
-            do_pci_remove(egc, domid, pci, prs->force, prs);
+            do_pci_remove(egc, prs);
             return;
         }
     }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:38 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:38 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54513.94768 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHa-0005qG-7h; Tue, 15 Dec 2020 16:34:38 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54513.94768; Tue, 15 Dec 2020 16:34:38 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHa-0005q8-4f; Tue, 15 Dec 2020 16:34:38 +0000
Received: by outflank-mailman (input) for mailman id 54513;
 Tue, 15 Dec 2020 16:34:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHZ-0005px-3O
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHZ-0002rs-2c
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHZ-0005Ne-1m
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=f2mOFsfWmyGOsWyOExs8aZLUb4ViSfm6vD8ds6jDTRk=; b=Ngg/CBVzzPF4NTsvaZmuR2SDAB
	87T60RFJy0wjxfNxc6otQ4tEW0MVG0q1Yc8/CQKNZA07oOeXfwxPX5MB9jIVyipo+yeZDNXU90iDr
	N7RgajiXrUXXB0nbDHlKasGIGQQKUxWf/2+Tu2wVBz2wcJJx3y0LbLAeq0DfVmyN8uYA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: stop using aodev->device_config in libxl__device_pci_add()...
Message-Id: <E1kpDHZ-0005Ne-1m@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:37 +0000

commit b5429d65e1827c4086b2195f594574abd65eb46d
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:16 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: stop using aodev->device_config in libxl__device_pci_add()...
    
    ... to hold a pointer to the device.
    
    There is already a 'pci' field in 'pci_add_state' so simply use that from
    the start. This also allows the 'pci' (#3) argument to be dropped from
    do_pci_add().
    
    NOTE: This patch also changes the type of the 'pci_domid' field in
          'pci_add_state' from 'int' to 'libxl_domid' which is more appropriate
          given what the field is used for.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index bcc4d2ef96..be2145222d 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1074,7 +1074,7 @@ typedef struct pci_add_state {
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
     libxl_device_pci *pci;
-    int pci_domid;
+    libxl_domid pci_domid;
 } pci_add_state;
 
 static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
@@ -1091,7 +1091,6 @@ static void pci_add_dm_done(libxl__egc *,
 
 static void do_pci_add(libxl__egc *egc,
                        libxl_domid domid,
-                       libxl_device_pci *pci,
                        pci_add_state *pas)
 {
     STATE_AO_GC(pas->aodev->ao);
@@ -1101,7 +1100,6 @@ static void do_pci_add(libxl__egc *egc,
     /* init pci_add_state */
     libxl__xswait_init(&pas->xswait);
     libxl__ev_qmp_init(&pas->qmp);
-    pas->pci = pci;
     pas->pci_domid = domid;
     libxl__ev_time_init(&pas->timeout);
 
@@ -1564,13 +1562,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     int stubdomid = 0;
     pci_add_state *pas;
 
-    /* Store *pci to be used by callbacks */
-    aodev->device_config = pci;
-    aodev->device_type = &libxl__pci_devtype;
-
     GCNEW(pas);
     pas->aodev = aodev;
     pas->domid = domid;
+    pas->pci = pci;
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
@@ -1624,9 +1619,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         GCNEW(pci_s);
         libxl_device_pci_init(pci_s);
         libxl_device_pci_copy(CTX, pci_s, pci);
+        pas->pci = pci_s;
         pas->callback = device_pci_add_stubdom_wait;
 
-        do_pci_add(egc, stubdomid, pci_s, pas); /* must be last */
+        do_pci_add(egc, stubdomid, pas); /* must be last */
         return;
     }
 
@@ -1681,9 +1677,8 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
     int i;
 
     /* Convenience aliases */
-    libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = aodev->device_config;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) goto out;
 
@@ -1718,7 +1713,7 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
                 pci->vdevfn = orig_vdev;
             }
             pas->callback = device_pci_add_done;
-            do_pci_add(egc, domid, pci, pas); /* must be last */
+            do_pci_add(egc, domid, pas); /* must be last */
             return;
         }
     }
@@ -1734,7 +1729,7 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = aodev->device_config;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) {
         LOGD(ERROR, domid,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:48 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54514.94772 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHk-0005rq-9C; Tue, 15 Dec 2020 16:34:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54514.94772; Tue, 15 Dec 2020 16:34:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHk-0005ri-6C; Tue, 15 Dec 2020 16:34:48 +0000
Received: by outflank-mailman (input) for mailman id 54514;
 Tue, 15 Dec 2020 16:34:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHj-0005rY-6L
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHj-0002s6-5d
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHj-0005Op-4k
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=om3Xxi7pkZxjhSlIFZq4N46UOtssv96ba2XMTTxwKJ8=; b=XZIuA/wpY8CP+peWTn6fG8Fxkw
	0gUrYUTBrHWu2lZLCkjd7DcRJ/TlJN1LWExmBM1IqWUsmigSxRSpy/cPXWfoB4TXRZbbtWJHHQCGK
	rrvMhfwRdQ4Exuwq4zINesKQ1tkTwsIQG9aYi0PAcK7q7q5sRVIYxf2DYmJ4PqnGdlGc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: generalise 'driver_path' xenstore access functions in libxl_pci.c
Message-Id: <E1kpDHj-0005Op-4k@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:47 +0000

commit fe91a3aadc038adbc2954e9a66e88493121a232e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:17 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: generalise 'driver_path' xenstore access functions in libxl_pci.c
    
    For the purposes of re-binding a device to its previous driver
    libxl__device_pci_assignable_add() writes the driver path into xenstore.
    This path is then read back in libxl__device_pci_assignable_remove().
    
    The functions that support this writing to and reading from xenstore are
    currently dedicated for this purpose and hence the node name 'driver_path'
    is hard-coded. This patch generalizes these utility functions and passes
    'driver_path' as an argument. Subsequent patches will invoke them to
    access other nodes.
    
    NOTE: Because functions will have a broader use (other than storing a
          driver path in lieu of pciback) the base xenstore path is also
          changed from '/libxl/pciback' to '/libxl/pci'.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 66 +++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index be2145222d..78ee641e9a 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -737,48 +737,46 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-#define PCIBACK_INFO_PATH "/libxl/pciback"
+#define PCI_INFO_PATH "/libxl/pci"
 
-static void pci_assignable_driver_path_write(libxl__gc *gc,
-                                            libxl_device_pci *pci,
-                                            char *driver_path)
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
 {
-    char *path;
+    return node ?
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
+                  pci->domain, pci->bus, pci->dev, pci->func,
+                  node) :
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
+                  pci->domain, pci->bus, pci->dev, pci->func);
+}
+
+
+static void pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node, const char *val)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
 
-    path = GCSPRINTF(PCIBACK_INFO_PATH"/"PCI_BDF_XSPATH"/driver_path",
-                     pci->domain,
-                     pci->bus,
-                     pci->dev,
-                     pci->func);
-    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", driver_path) < 0 ) {
-        LOGE(WARN, "Write of %s to node %s failed.", driver_path, path);
+    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", val) < 0 ) {
+        LOGE(WARN, "Write of %s to node %s failed.", val, path);
     }
 }
 
-static char * pci_assignable_driver_path_read(libxl__gc *gc,
-                                              libxl_device_pci *pci)
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
 {
-    return libxl__xs_read(gc, XBT_NULL,
-                          GCSPRINTF(
-                           PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH "/driver_path",
-                           pci->domain,
-                           pci->bus,
-                           pci->dev,
-                           pci->func));
+    char *path = pci_info_xs_path(gc, pci, node);
+
+    return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_assignable_driver_path_remove(libxl__gc *gc,
-                                              libxl_device_pci *pci)
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+                               const char *node)
 {
+    char *path = pci_info_xs_path(gc, pci, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
-    xs_rm(ctx->xsh, XBT_NULL,
-          GCSPRINTF(PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH,
-                    pci->domain,
-                    pci->bus,
-                    pci->dev,
-                    pci->func) );
+    xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
@@ -824,9 +822,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_assignable_driver_path_write(gc, pci, driver_path);
+            pci_info_xs_write(gc, pci, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_assignable_driver_path_read(gc, pci)) != NULL ) {
+                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -834,7 +832,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_assignable_driver_path_remove(gc, pci);
+        pci_info_xs_remove(gc, pci, "driver_path");
     }
 
     if ( pciback_dev_assign(gc, pci) ) {
@@ -884,7 +882,7 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     }
 
     /* Rebind if necessary */
-    driver_path = pci_assignable_driver_path_read(gc, pci);
+    driver_path = pci_info_xs_read(gc, pci, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -897,7 +895,7 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
                 return -1;
             }
 
-            pci_assignable_driver_path_remove(gc, pci);
+            pci_info_xs_remove(gc, pci, "driver_path");
         }
     } else {
         if ( rebind ) {
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:34:58 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:34:58 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54515.94776 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHu-0005tF-Au; Tue, 15 Dec 2020 16:34:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54515.94776; Tue, 15 Dec 2020 16:34:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDHu-0005t6-7o; Tue, 15 Dec 2020 16:34:58 +0000
Received: by outflank-mailman (input) for mailman id 54515;
 Tue, 15 Dec 2020 16:34:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHt-0005sy-9P
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHt-0002sF-8i
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDHt-0005QU-7o
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:34:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DySGysWIBzXtwvhahNh15cPHWO/IWXn37ANXYlVN3kU=; b=p+Fw23Sm0bCSKVzqsyyZsRoKME
	enEZMlfoM74/BvmBglP2dNWs9hxPTB57OVAdFe7r37Bc21VVhCJzoh8Vb0M7QVURauN75RBoWbVk4
	vpYPsbSUx2D4FAanp15lryT85KXBCasXfXqOI17N2wDpmAW7aCu+Hc9elAEEaWwUdLUM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: remove unnecessary check from libxl__device_pci_add()
Message-Id: <E1kpDHt-0005QU-7o@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:34:57 +0000

commit 4951b9ea807d4a4e5a54798d366b2ea3d6ca5060
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:18 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove unnecessary check from libxl__device_pci_add()
    
    The code currently checks explicitly whether the device is already assigned,
    but this is actually unnecessary as assigned devices do not form part of
    the list returned by libxl_device_pci_assignable_list() and hence the
    libxl_pci_assignable() test would have already failed.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 78ee641e9a..0c2ab5075d 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1555,8 +1555,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 {
     STATE_AO_GC(aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    libxl_device_pci *assigned;
-    int num_assigned, rc;
+    int rc;
     int stubdomid = 0;
     pci_add_state *pas;
 
@@ -1595,19 +1594,6 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         goto out;
     }
 
-    rc = get_all_assigned_devices(gc, &assigned, &num_assigned);
-    if ( rc ) {
-        LOGD(ERROR, domid,
-             "cannot determine if device is assigned, refusing to continue");
-        goto out;
-    }
-    if ( is_pci_in_array(assigned, num_assigned, pci->domain,
-                         pci->bus, pci->dev, pci->func) ) {
-        LOGD(ERROR, domid, "PCI device already attached to a domain");
-        rc = ERROR_FAIL;
-        goto out;
-    }
-
     libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54516.94780 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDI4-0005uk-Dm; Tue, 15 Dec 2020 16:35:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54516.94780; Tue, 15 Dec 2020 16:35:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDI4-0005uc-Ac; Tue, 15 Dec 2020 16:35:08 +0000
Received: by outflank-mailman (input) for mailman id 54516;
 Tue, 15 Dec 2020 16:35:07 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDI3-0005uS-Cf
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:07 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDI3-0002sa-Bp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDI3-0005Sg-Au
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OzBy+dzmFhNbtcpGBv1nWNr5js8Nbw8zaX7o214/nGE=; b=wJyew5lGzdoh5zfqbeIcXmSUSy
	O8STi8N8SDv1Qb42HkSBwNf2CkZ4yOC5zHUaD6h5dhZtUEjUuz3zQdiOuZMmtUwVEKdOltu/H+tDP
	8wp6ur86wTMFMLje7fNj2S2FzBdxVg8zwootcODnGIbFyaHu/NIbccxjbUI0WEToQ1jQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: remove get_all_assigned_devices() from libxl_pci.c
Message-Id: <E1kpDI3-0005Sg-Au@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:07 +0000

commit f8cfb85719b600f3f87a1a3931f292f4335dcce4
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:19 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove get_all_assigned_devices() from libxl_pci.c
    
    Use of this function is a very inefficient way to check whether a device
    has already been assigned.
    
    This patch adds code that saves the domain id in xenstore at the point of
    assignment, and removes it again when the device id de-assigned (or the
    domain is destroyed). It is then straightforward to check whether a device
    has been assigned by checking whether a device has a saved domain id.
    
    NOTE: To facilitate the xenstore check it is necessary to move the
          pci_info_xs_read() earlier in libxl_pci.c. To keep related functions
          together, the rest of the pci_info_xs_XXX() functions are moved too.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 149 ++++++++++++++++---------------------------
 1 file changed, 55 insertions(+), 94 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 0c2ab5075d..37a6ec9eb4 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -336,50 +336,6 @@ retry_transaction2:
     return 0;
 }
 
-static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int *num)
-{
-    char **domlist;
-    unsigned int nd = 0, i;
-
-    *list = NULL;
-    *num = 0;
-
-    domlist = libxl__xs_directory(gc, XBT_NULL, "/local/domain", &nd);
-    for(i = 0; i < nd; i++) {
-        char *path, *num_devs;
-
-        path = GCSPRINTF("/local/domain/0/backend/%s/%s/0/num_devs",
-                         libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI),
-                         domlist[i]);
-        num_devs = libxl__xs_read(gc, XBT_NULL, path);
-        if ( num_devs ) {
-            int ndev = atoi(num_devs), j;
-            char *devpath, *bdf;
-
-            for(j = 0; j < ndev; j++) {
-                devpath = GCSPRINTF("/local/domain/0/backend/%s/%s/0/dev-%u",
-                                    libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI),
-                                    domlist[i], j);
-                bdf = libxl__xs_read(gc, XBT_NULL, devpath);
-                if ( bdf ) {
-                    unsigned dom, bus, dev, func;
-                    if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
-                        continue;
-
-                    *list = realloc(*list, sizeof(libxl_device_pci) * ((*num) + 1));
-                    if (*list == NULL)
-                        return ERROR_NOMEM;
-                    pci_struct_fill(*list + *num, dom, bus, dev, func, 0);
-                    (*num)++;
-                }
-            }
-        }
-    }
-    libxl__ptr_add(gc, *list);
-
-    return 0;
-}
-
 static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
                            int dom, int bus, int dev, int func)
 {
@@ -427,19 +383,58 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
     return 0;
 }
 
+#define PCI_INFO_PATH "/libxl/pci"
+
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
+{
+    return node ?
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
+                  pci->domain, pci->bus, pci->dev, pci->func,
+                  node) :
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
+                  pci->domain, pci->bus, pci->dev, pci->func);
+}
+
+
+static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node, const char *val)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+    int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
+
+    if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
+
+    return rc;
+}
+
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+
+    return libxl__xs_read(gc, XBT_NULL, path);
+}
+
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+                               const char *node)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+
+    /* Remove the xenstore entry */
+    xs_rm(ctx->xsh, XBT_NULL, path);
+}
+
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcis = NULL, *new, *assigned;
+    libxl_device_pci *pcis = NULL, *new;
     struct dirent *de;
     DIR *dir;
-    int r, num_assigned;
 
     *num = 0;
 
-    r = get_all_assigned_devices(gc, &assigned, &num_assigned);
-    if (r) goto out;
-
     dir = opendir(SYSFS_PCIBACK_DRIVER);
     if (NULL == dir) {
         if (errno == ENOENT) {
@@ -455,9 +450,6 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        if (is_pci_in_array(assigned, num_assigned, dom, bus, dev, func))
-            continue;
-
         new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
@@ -467,6 +459,10 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 
         memset(new, 0, sizeof(*new));
         pci_struct_fill(new, dom, bus, dev, func, 0);
+
+        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
+            continue;
+
         (*num)++;
     }
 
@@ -737,48 +733,6 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-#define PCI_INFO_PATH "/libxl/pci"
-
-static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node)
-{
-    return node ?
-        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->domain, pci->bus, pci->dev, pci->func,
-                  node) :
-        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->domain, pci->bus, pci->dev, pci->func);
-}
-
-
-static void pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node, const char *val)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-
-    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", val) < 0 ) {
-        LOGE(WARN, "Write of %s to node %s failed.", val, path);
-    }
-}
-
-static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-
-    return libxl__xs_read(gc, XBT_NULL, path);
-}
-
-static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
-                               const char *node)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-
-    /* Remove the xenstore entry */
-    xs_rm(ctx->xsh, XBT_NULL, path);
-}
-
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
                                             libxl_device_pci *pci,
                                             int rebind)
@@ -1594,6 +1548,9 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         goto out;
     }
 
+    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
+    if (rc) goto out;
+
     libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
@@ -1721,6 +1678,7 @@ static void device_pci_add_done(libxl__egc *egc,
              "PCI device %x:%x:%x.%x (rc %d)",
              pci->domain, pci->bus, pci->dev, pci->func,
              rc);
+        pci_info_xs_remove(gc, pci, "domid");
     }
     aodev->rc = rc;
     aodev->callback(egc, aodev);
@@ -2282,6 +2240,9 @@ out:
     libxl__xswait_stop(gc, &prs->xswait);
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
+
+    if (!rc) pci_info_xs_remove(gc, pci, "domid");
+
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:18 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:18 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54517.94784 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIE-0005w4-FP; Tue, 15 Dec 2020 16:35:18 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54517.94784; Tue, 15 Dec 2020 16:35:18 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIE-0005vu-CA; Tue, 15 Dec 2020 16:35:18 +0000
Received: by outflank-mailman (input) for mailman id 54517;
 Tue, 15 Dec 2020 16:35:17 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDID-0005vk-G5
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:17 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDID-0002si-FL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:17 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDID-0005UK-EL
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:17 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jFZyGJnZvAjv2h4CHeYMqDvsx7IueOrHo8RAx9dx0VA=; b=rlMpss4jsj0zgpuKuvohGsVb1d
	pfGjy8vQZXz6jjVCWXXJwk58tWi1ChUWZ1cMObT8PLqoZZikiUDxdjSOLPDIh7nVucHHk5nzH44qA
	AZLN1UHBfMMvd9ow0uWI57dqwxuWDLwOpnERIPgPX05n9UuPF8Eip9evgsnyjOlaSS1Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: make sure callers of libxl_device_pci_list() free the list after use
Message-Id: <E1kpDID-0005UK-EL@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:17 +0000

commit 7499b22ba1f68237c201da8534706dbe430987d5
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:20 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: make sure callers of libxl_device_pci_list() free the list after use
    
    A previous patch introduced libxl_device_pci_list_free() which should be used
    by callers of libxl_device_pci_list() to properly dispose of the exported
    'libxl_device_pci' types and the free the memory holding them. Whilst all
    current callers do ensure the memory is freed, only the code in xl's
    pcilist() function actually calls libxl_device_pci_dispose(). As it stands
    this laxity does not lead to any memory leaks, but the simple addition of
    .e.g. a 'string' into the idl definition of 'libxl_device_pci' would lead
    to leaks.
    
    This patch makes sure all callers of libxl_device_pci_list() can call
    libxl_device_pci_list_free() by keeping copies of 'libxl_device_pci'
    structures inline in 'pci_add_state' and 'pci_remove_state' (and also making
    sure these are properly disposed at the end of the operations) rather
    than keeping pointers to the structures returned by libxl_device_pci_list().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 68 ++++++++++++++++++++++++--------------------
 tools/xl/xl_pci.c            |  3 +-
 2 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 37a6ec9eb4..c555f3ed29 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1025,7 +1025,7 @@ typedef struct pci_add_state {
     libxl__xswait_state xswait;
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
-    libxl_device_pci *pci;
+    libxl_device_pci pci;
     libxl_domid pci_domid;
 } pci_add_state;
 
@@ -1097,7 +1097,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1118,7 +1118,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
     libxl__ev_qmp *const qmp = &pas->qmp;
 
     rc = libxl__ev_time_register_rel(ao, &pas->timeout,
@@ -1199,7 +1199,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
     int dev_slot, dev_func;
 
     /* Convenience aliases */
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) goto out;
 
@@ -1300,7 +1300,7 @@ static void pci_add_dm_done(libxl__egc *egc,
 
     /* Convenience aliases */
     bool starting = pas->starting;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
     bool hvm = libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM;
 
     libxl__ev_qmp_dispose(gc, &pas->qmp);
@@ -1516,7 +1516,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     GCNEW(pas);
     pas->aodev = aodev;
     pas->domid = domid;
-    pas->pci = pci;
+
+    libxl_device_pci_copy(CTX, &pas->pci, pci);
+    pci = &pas->pci;
+
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
@@ -1555,12 +1558,6 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pci_s;
-
-        GCNEW(pci_s);
-        libxl_device_pci_init(pci_s);
-        libxl_device_pci_copy(CTX, pci_s, pci);
-        pas->pci = pci_s;
         pas->callback = device_pci_add_stubdom_wait;
 
         do_pci_add(egc, stubdomid, pas); /* must be last */
@@ -1619,7 +1616,7 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) goto out;
 
@@ -1670,7 +1667,7 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
         LOGD(ERROR, domid,
@@ -1680,6 +1677,7 @@ static void device_pci_add_done(libxl__egc *egc,
              rc);
         pci_info_xs_remove(gc, pci, "domid");
     }
+    libxl_device_pci_dispose(pci);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
@@ -1770,7 +1768,7 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
 typedef struct pci_remove_state {
     libxl__ao_device *aodev;
     libxl_domid domid;
-    libxl_device_pci *pci;
+    libxl_device_pci pci;
     bool force;
     bool hvm;
     unsigned int orig_vdev;
@@ -1812,23 +1810,26 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    libxl_device_pci *assigned;
+    libxl_device_pci *pcis;
+    bool attached;
     uint32_t domid = prs->domid;
     libxl_domain_type type = libxl__domain_type(gc, domid);
-    libxl_device_pci *pci = prs->pci;
+    libxl_device_pci *pci = &prs->pci;
     int rc, num;
     uint32_t domainid = domid;
 
-    assigned = libxl_device_pci_list(ctx, domid, &num);
-    if (assigned == NULL) {
+    pcis = libxl_device_pci_list(ctx, domid, &num);
+    if (!pcis) {
         rc = ERROR_FAIL;
         goto out_fail;
     }
-    libxl__ptr_add(gc, assigned);
+
+    attached = is_pci_in_array(pcis, num, pci->domain,
+                               pci->bus, pci->dev, pci->func);
+    libxl_device_pci_list_free(pcis, num);
 
     rc = ERROR_INVAL;
-    if ( !is_pci_in_array(assigned, num, pci->domain,
-                          pci->bus, pci->dev, pci->func) ) {
+    if (!attached) {
         LOGD(ERROR, domainid, "PCI device not attached to this domain");
         goto out_fail;
     }
@@ -1928,7 +1929,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1950,7 +1951,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     int rc;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     rc = libxl__ev_time_register_rel(ao, &prs->timeout,
                                      pci_remove_timeout,
@@ -2020,7 +2021,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl__ao *const ao = prs->aodev->ao;
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     if (rc) goto out;
 
@@ -2075,7 +2076,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     pci_remove_state *prs = CONTAINER_OF(ev, *prs, timeout);
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
          PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
@@ -2096,7 +2097,7 @@ static void pci_remove_detached(libxl__egc *egc,
     bool isstubdom;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
     libxl_domid domid = prs->domid;
 
     /* Cleaning QMP states ASAP */
@@ -2159,7 +2160,7 @@ static void pci_remove_done(libxl__egc *egc,
 
     if (rc) goto out;
 
-    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pci);
+    libxl__device_pci_remove_xenstore(gc, prs->domid, &prs->pci);
 out:
     device_pci_remove_common_next(egc, prs, rc);
 }
@@ -2177,7 +2178,10 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     GCNEW(prs);
     prs->aodev = aodev;
     prs->domid = domid;
-    prs->pci = pci;
+
+    libxl_device_pci_copy(CTX, &prs->pci, pci);
+    pci = &prs->pci;
+
     prs->force = force;
     libxl__xswait_init(&prs->xswait);
     libxl__ev_qmp_init(&prs->qmp);
@@ -2212,7 +2216,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
     EGC_GC;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
     const unsigned int orig_vdev = prs->orig_vdev;
@@ -2243,6 +2247,7 @@ out:
 
     if (!rc) pci_info_xs_remove(gc, pci, "domid");
 
+    libxl_device_pci_dispose(pci);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
@@ -2357,7 +2362,6 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
     pcis = libxl_device_pci_list(CTX, domid, &num);
     if ( pcis == NULL )
         return;
-    libxl__ptr_add(gc, pcis);
 
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
@@ -2368,6 +2372,8 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
         libxl__device_pci_remove_common(egc, domid, pcis + i, true,
                                         aodev);
     }
+
+    libxl_device_pci_list_free(pcis, num);
 }
 
 int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid,
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 34fcf5a4fa..7c0f102ac7 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -35,9 +35,8 @@ static void pcilist(uint32_t domid)
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
                pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
-        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcis);
+    libxl_device_pci_list_free(pcis, num);
 }
 
 int main_pcilist(int argc, char **argv)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54518.94787 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIO-0005xY-Gc; Tue, 15 Dec 2020 16:35:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54518.94787; Tue, 15 Dec 2020 16:35:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIO-0005xQ-Dk; Tue, 15 Dec 2020 16:35:28 +0000
Received: by outflank-mailman (input) for mailman id 54518;
 Tue, 15 Dec 2020 16:35:27 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIN-0005xJ-JS
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:27 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIN-0002sq-In
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:27 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIN-0005Uy-Hu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:27 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2cUITTzPXTL/frXkMQv9cZxANK6d31ku+4iQcd2T6Mw=; b=Q4JE2CRiwlDWLbpl4X5re8UKQx
	Afa/lDYyupibyXHlSHsYwsg8kNp1sSutEboGwuCNy3KHD6wZ8IOlyXR55EOjzAgnDTH+6GFAEBLPt
	wlBJox9SDDYzbW433t18l3U3Wb+gfgq2sqYk68eCBD0cjtHRJyNKz6FWhbKIlos2h0kE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: add libxl_device_pci_assignable_list_free()...
Message-Id: <E1kpDIN-0005Uy-Hu@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:27 +0000

commit c00da823550d0ff63d99b1b48effd6728bee156e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:21 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: add libxl_device_pci_assignable_list_free()...
    
    ... to be used by callers of libxl_device_pci_assignable_list().
    
    Currently there is no API for callers of libxl_device_pci_assignable_list()
    to free the list. The xl function pciassignable_list() calls
    libxl_device_pci_dispose() on each element of the returned list, but
    libxl_pci_assignable() in libxl_pci.c does not. Neither does the implementation
    of libxl_device_pci_assignable_list() call libxl_device_pci_init().
    
    This patch adds the new API function, makes sure it is used everywhere and
    also modifies libxl_device_pci_assignable_list() to initialize list
    entries rather than just zeroing them.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h                |  7 +++++++
 tools/libs/light/libxl_pci.c         | 14 ++++++++++++--
 tools/ocaml/libs/xl/xenlight_stubs.c |  3 +--
 tools/xl/xl_pci.c                    |  3 +--
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index bb7fc893fc..3433c950f9 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -457,6 +457,12 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_LIST_FREE 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE indicates that the
+ * libxl_device_pci_assignable_list_free() function is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2369,6 +2375,7 @@ int libxl_device_events_handler(libxl_ctx *ctx,
 int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
 int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str);
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index c555f3ed29..2a594e4328 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -457,7 +457,7 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         pcis = new;
         new = pcis + *num;
 
-        memset(new, 0, sizeof(*new));
+        libxl_device_pci_init(new);
         pci_struct_fill(new, dom, bus, dev, func, 0);
 
         if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
@@ -472,6 +472,16 @@ out:
     return pcis;
 }
 
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+{
+    int i;
+
+    for (i = 0; i < num; i++)
+        libxl_device_pci_dispose(&list[i]);
+
+    free(list);
+}
+
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
 static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
@@ -1490,7 +1500,7 @@ static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
             pcis[i].func == pci->func)
             break;
     }
-    free(pcis);
+    libxl_device_pci_assignable_list_free(pcis, num);
     return i != num;
 }
 
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c
index 1181971da4..352a00134d 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -894,9 +894,8 @@ value stub_xl_device_pci_assignable_list(value ctx)
 		Field(list, 1) = temp;
 		temp = list;
 		Store_field(list, 0, Val_device_pci(&c_list[i]));
-		libxl_device_pci_dispose(&c_list[i]);
 	}
-	free(c_list);
+	libxl_device_pci_assignable_list_free(c_list, nb);
 
 	CAMLreturn(list);
 }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 7c0f102ac7..f71498cbb5 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -164,9 +164,8 @@ static void pciassignable_list(void)
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
                pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
-        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcis);
+    libxl_device_pci_assignable_list_free(pcis, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:39 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:39 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54519.94793 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIZ-0005zF-KS; Tue, 15 Dec 2020 16:35:39 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54519.94793; Tue, 15 Dec 2020 16:35:39 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIZ-0005z7-FK; Tue, 15 Dec 2020 16:35:39 +0000
Received: by outflank-mailman (input) for mailman id 54519;
 Tue, 15 Dec 2020 16:35:37 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIX-0005ym-Mu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:37 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIX-0002tJ-M9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:37 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIX-0005WA-LJ
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:37 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=t+2WGpuxgKbKlvTnI48fkWq71mnRs/ljTgMqB2/gbjA=; b=JksQJcZwye8WvTLq/IzDKKdUdH
	ouX+huCa97HgSsL5RzOoTg7joDdc+20/oEYQIBelLFW+nLFcqLi/ZXos46RvvUz4MVD1/5zAT3Xkp
	wqz8JFri1OL/SRRvguSofMgDD6NuSJ4nzW1EeDZuAufcpzPIepP3gnUBsy7QnQNj/6Ek=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: use COMPARE_PCI() macro is_pci_in_array()...
Message-Id: <E1kpDIX-0005WA-LJ@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:37 +0000

commit 413fd4e4e958081dea06dcad37c1526f7e846732
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:22 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: use COMPARE_PCI() macro is_pci_in_array()...
    
    ... rather than an open-coded equivalent.
    
    This patch tidies up the is_pci_in_array() function, making it take a single
    'libxl_device_pci' argument rather than separate domain, bus, device and
    function arguments. The already-available COMPARE_PCI() macro can then be
    used and it is also modified to return 'bool' rather than 'int'.
    
    The patch also modifies libxl_pci_assignable() to use is_pci_in_array() rather
    than a separate open-coded equivalent, and also modifies it to return a
    'bool' rather than an 'int'.
    
    NOTE: The COMPARE_PCI() macro is also fixed to include the 'domain' in its
          comparison, which should always have been the case.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_internal.h |  7 ++++---
 tools/libs/light/libxl_pci.c      | 38 +++++++++++++-------------------------
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index d0c23def3c..c79523ba92 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,9 +4746,10 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_PCI(a, b) ((a)->func == (b)->func &&    \
-                           (a)->bus == (b)->bus &&      \
-                           (a)->dev == (b)->dev)
+#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
+                           (a)->bus == (b)->bus &&       \
+                           (a)->dev == (b)->dev &&       \
+                           (a)->func == (b)->func)
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 2a594e4328..74c2196ae3 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -336,24 +336,17 @@ retry_transaction2:
     return 0;
 }
 
-static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
-                           int dom, int bus, int dev, int func)
+static bool is_pci_in_array(libxl_device_pci *pcis, int num,
+                            libxl_device_pci *pci)
 {
     int i;
 
-    for(i = 0; i < num_assigned; i++) {
-        if ( assigned[i].domain != dom )
-            continue;
-        if ( assigned[i].bus != bus )
-            continue;
-        if ( assigned[i].dev != dev )
-            continue;
-        if ( assigned[i].func != func )
-            continue;
-        return 1;
+    for (i = 0; i < num; i++) {
+        if (COMPARE_PCI(pci, &pcis[i]))
+            break;
     }
 
-    return 0;
+    return i < num;
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
@@ -1487,21 +1480,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
+static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
     libxl_device_pci *pcis;
-    int num, i;
+    int num;
+    bool assignable;
 
     pcis = libxl_device_pci_assignable_list(ctx, &num);
-    for (i = 0; i < num; i++) {
-        if (pcis[i].domain == pci->domain &&
-            pcis[i].bus == pci->bus &&
-            pcis[i].dev == pci->dev &&
-            pcis[i].func == pci->func)
-            break;
-    }
+    assignable = is_pci_in_array(pcis, num, pci);
     libxl_device_pci_assignable_list_free(pcis, num);
-    return i != num;
+
+    return assignable;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1834,8 +1823,7 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         goto out_fail;
     }
 
-    attached = is_pci_in_array(pcis, num, pci->domain,
-                               pci->bus, pci->dev, pci->func);
+    attached = is_pci_in_array(pcis, num, pci);
     libxl_device_pci_list_free(pcis, num);
 
     rc = ERROR_INVAL;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:49 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54522.94800 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIj-00061i-Ni; Tue, 15 Dec 2020 16:35:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54522.94800; Tue, 15 Dec 2020 16:35:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIj-00061a-Kj; Tue, 15 Dec 2020 16:35:49 +0000
Received: by outflank-mailman (input) for mailman id 54522;
 Tue, 15 Dec 2020 16:35:47 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIh-00061K-Pp
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:47 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIh-0002tR-P4
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:47 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIh-0005X4-OG
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:47 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=K0yDhW/mUre0pE8lPM9vXaKT3LFom4o8jXZ9n+VxLRg=; b=osbYEtcw328TbobzBXsN6M31NY
	SuT/zzGlpSfhTpr00WNDODOkws2FS7g0iQpf1Bwtb//I6a5566shszI6RuqxaWzt8BHPLeY3hEQUp
	EveTqlg+rbuJ2Nm9TAcngVRUBw8CSXU+Tvts9R94uRMI9+OmPYYXu+L7RWi4bd76gw8s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs/man: extract documentation of PCI_SPEC_STRING from the xl.cfg manpage...
Message-Id: <E1kpDIh-0005X4-OG@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:47 +0000

commit 581abb66a9ee5de403c97b2520960f65a878a0ff
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:23 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: extract documentation of PCI_SPEC_STRING from the xl.cfg manpage...
    
    ... and put it into a new xl-pci-configuration(5) manpage, akin to the
    xl-network-configration(5) and xl-disk-configuration(5) manpages.
    
    This patch moves the content of the section verbatim. A subsequent patch
    will improve the documentation, once it is in its new location.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 78 +++++++++++++++++++++++++++++++++++++
 docs/man/xl.cfg.5.pod.in            | 68 +-------------------------------
 2 files changed, 79 insertions(+), 67 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
new file mode 100644
index 0000000000..72a27bd95d
--- /dev/null
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -0,0 +1,78 @@
+=encoding utf8
+
+=head1 NAME
+
+xl-pci-configuration - XL PCI Configuration Syntax
+
+=head1 SYNTAX
+
+This document specifies the format for B<PCI_SPEC_STRING> which is used by
+the L<xl.cfg(5)> pci configuration option, and related L<xl(1)> commands.
+
+Each B<PCI_SPEC_STRING> has the form of
+B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
+
+=over 4
+
+=item B<[DDDD:]BB:DD.F>
+
+Identifies the PCI device from the host perspective in the domain
+(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
+the same scheme as used in the output of B<lspci(1)> for the device in
+question.
+
+Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
+is zero and it is optional here also. You may specify the function
+(B<F>) as B<*> to indicate all functions.
+
+=item B<@VSLOT>
+
+Specifies the virtual slot where the guest will see this
+device. This is equivalent to the B<DD> which the guest sees. In a
+guest B<DDDD> and B<BB> are C<0000:00>.
+
+=item B<permissive=BOOLEAN>
+
+By default pciback only allows PV guests to write "known safe" values
+into PCI configuration space, likewise QEMU (both qemu-xen and
+qemu-xen-traditional) imposes the same constraint on HVM guests.
+However, many devices require writes to other areas of the configuration space
+in order to operate properly.  This option tells the backend (pciback or QEMU)
+to allow all writes to the PCI configuration space of this device by this
+domain.
+
+B<This option should be enabled with caution:> it gives the guest much
+more control over the device, which may have security or stability
+implications.  It is recommended to only enable this option for
+trusted VMs under administrator's control.
+
+=item B<msitranslate=BOOLEAN>
+
+Specifies that MSI-INTx translation should be turned on for the PCI
+device. When enabled, MSI-INTx translation will always enable MSI on
+the PCI device regardless of whether the guest uses INTx or MSI. Some
+device drivers, such as NVIDIA's, detect an inconsistency and do not
+function when this option is enabled. Therefore the default is false (0).
+
+=item B<seize=BOOLEAN>
+
+Tells B<xl> to automatically attempt to re-assign a device to
+pciback if it is not already assigned.
+
+B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
+system device, such as a network or a disk controller being used by
+dom0 without confirmation.  Please use with care.
+
+=item B<power_mgmt=BOOLEAN>
+
+B<(HVM only)> Specifies that the VM should be able to program the
+D0-D3hot power management states for the PCI device. The default is false (0).
+
+=item B<rdm_policy=STRING>
+
+B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
+option but just specific to a given device. The default is "relaxed".
+
+Note: this would override global B<rdm> option.
+
+=back
diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 12201a7e54..c8e017f950 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -1101,73 +1101,7 @@ option is valid only when the B<controller> option is specified.
 =item B<pci=[ "PCI_SPEC_STRING", "PCI_SPEC_STRING", ...]>
 
 Specifies the host PCI devices to passthrough to this guest.
-Each B<PCI_SPEC_STRING> has the form of
-B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
-
-=over 4
-
-=item B<[DDDD:]BB:DD.F>
-
-Identifies the PCI device from the host perspective in the domain
-(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
-the same scheme as used in the output of B<lspci(1)> for the device in
-question.
-
-Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
-is zero and it is optional here also. You may specify the function
-(B<F>) as B<*> to indicate all functions.
-
-=item B<@VSLOT>
-
-Specifies the virtual slot where the guest will see this
-device. This is equivalent to the B<DD> which the guest sees. In a
-guest B<DDDD> and B<BB> are C<0000:00>.
-
-=item B<permissive=BOOLEAN>
-
-By default pciback only allows PV guests to write "known safe" values
-into PCI configuration space, likewise QEMU (both qemu-xen and
-qemu-xen-traditional) imposes the same constraint on HVM guests.
-However, many devices require writes to other areas of the configuration space
-in order to operate properly.  This option tells the backend (pciback or QEMU)
-to allow all writes to the PCI configuration space of this device by this
-domain.
-
-B<This option should be enabled with caution:> it gives the guest much
-more control over the device, which may have security or stability
-implications.  It is recommended to only enable this option for
-trusted VMs under administrator's control.
-
-=item B<msitranslate=BOOLEAN>
-
-Specifies that MSI-INTx translation should be turned on for the PCI
-device. When enabled, MSI-INTx translation will always enable MSI on
-the PCI device regardless of whether the guest uses INTx or MSI. Some
-device drivers, such as NVIDIA's, detect an inconsistency and do not
-function when this option is enabled. Therefore the default is false (0).
-
-=item B<seize=BOOLEAN>
-
-Tells B<xl> to automatically attempt to re-assign a device to
-pciback if it is not already assigned.
-
-B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
-system device, such as a network or a disk controller being used by
-dom0 without confirmation.  Please use with care.
-
-=item B<power_mgmt=BOOLEAN>
-
-B<(HVM only)> Specifies that the VM should be able to program the
-D0-D3hot power management states for the PCI device. The default is false (0).
-
-=item B<rdm_policy=STRING>
-
-B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
-option but just specific to a given device. The default is "relaxed".
-
-Note: this would override global B<rdm> option.
-
-=back
+See L<xl-pci-configuration(5)> for more details.
 
 =item B<pci_permissive=BOOLEAN>
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:35:59 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:35:59 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54524.94804 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIt-00063H-PH; Tue, 15 Dec 2020 16:35:59 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54524.94804; Tue, 15 Dec 2020 16:35:59 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDIt-000639-MD; Tue, 15 Dec 2020 16:35:59 +0000
Received: by outflank-mailman (input) for mailman id 54524;
 Tue, 15 Dec 2020 16:35:57 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIr-00062w-TO
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:57 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIr-0002te-Sk
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:57 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDIr-0005Xw-RD
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:35:57 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sJz5gOhpBgZsujVhOeXQa7TIyHjD3o52VPGRn56wRlc=; b=cHfPEAAxUqrum6X2RiGkUFgU5U
	w5XG6k+44+dDvUzqxH9vAdLGxsLRDbTOvJVKGhaGsdkrUyT3jbZmOMVOU86xs4nKNrU6AmtoaNwqn
	94fmko76v39sNevwgn1paheZnAgPNLYc11W1A6SaQYhMGLCxYTY1kxiCAH4TE/l4uuQQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs/man: improve documentation of PCI_SPEC_STRING...
Message-Id: <E1kpDIr-0005Xw-RD@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:35:57 +0000

commit 3085930e2f55a51d33a664072c3045aa2cc94445
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:24 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: improve documentation of PCI_SPEC_STRING...
    
    ... and prepare for adding support for non-positional parsing of 'bdf' and
    'vslot' in a subsequent patch.
    
    Also document 'BDF' as a first-class parameter type and fix the documentation
    to state that the default value of 'rdm_policy' is actually 'strict', not
    'relaxed', as can be seen in libxl__device_pci_setdefault().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 177 ++++++++++++++++++++++++++++++------
 1 file changed, 148 insertions(+), 29 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index 72a27bd95d..4dd73bc498 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -6,32 +6,105 @@ xl-pci-configuration - XL PCI Configuration Syntax
 
 =head1 SYNTAX
 
-This document specifies the format for B<PCI_SPEC_STRING> which is used by
-the L<xl.cfg(5)> pci configuration option, and related L<xl(1)> commands.
+This document specifies the format for B<BDF> and B<PCI_SPEC_STRING> which are
+used by the L<xl.cfg(5)> pci configuration option, and related L<xl(1)>
+commands.
 
-Each B<PCI_SPEC_STRING> has the form of
-B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
+A B<BDF> has the following form:
+
+    [DDDD:]BB:SS.F
+
+B<DDDD> is the domain number, B<BB> is the bus number, B<SS> is the device (or
+slot) number, and B<F> is the function number. This is the same scheme as
+used in the output of L<lspci(1)> for the device in question. By default
+L<lspci(1)> will omit the domain (B<DDDD>) if it is zero and hence a zero
+value for domain may also be omitted when specifying a B<BDF>.
+
+Each B<PCI_SPEC_STRING> has the one of the forms:
+
+=over 4
+
+    [<bdf>[@<vslot>,][<key>=<value>,]*
+    [<key>=<value>,]*
+
+=back
+
+For example, these strings are equivalent:
 
 =over 4
 
-=item B<[DDDD:]BB:DD.F>
+    36:00.0@20,seize=1
+    36:00.0,vslot=20,seize=1
+    bdf=36:00.0,vslot=20,seize=1
 
-Identifies the PCI device from the host perspective in the domain
-(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
-the same scheme as used in the output of B<lspci(1)> for the device in
-question.
+=back
+
+More formally, the string is a series of comma-separated keyword/value
+pairs, flags and positional parameters.  Parameters which are not bare
+keywords and which do not contain "=" symbols are assigned to the
+positional parameters, in the order specified below.  The positional
+parameters may also be specified by name.
+
+Each parameter may be specified at most once, either as a positional
+parameter or a named parameter.  Default values apply if the parameter
+is not specified, or if it is specified with an empty value (whether
+positionally or explicitly).
+
+B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
+B<bdf> will be ignored.
+
+=head1 Positional Parameters
+
+=over 4
+
+=item B<bdf>=I<BDF>
+
+=over 4
 
-Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
-is zero and it is optional here also. You may specify the function
-(B<F>) as B<*> to indicate all functions.
+=item Description
 
-=item B<@VSLOT>
+This identifies the PCI device from the host perspective.
 
-Specifies the virtual slot where the guest will see this
-device. This is equivalent to the B<DD> which the guest sees. In a
-guest B<DDDD> and B<BB> are C<0000:00>.
+In the context of a B<PCI_SPEC_STRING> you may specify the function (B<F>) as
+B<*> to indicate all functions of a multi-function device.
 
-=item B<permissive=BOOLEAN>
+=item Default Value
+
+None. This parameter is mandatory as it identifies the device.
+
+=back
+
+=item B<vslot>=I<NUMBER>
+
+=over 4
+
+=item Description
+
+Specifies the virtual slot (device) number where the guest will see this
+device. For example, running L<lspci(1)> in a Linux guest where B<vslot>
+was specified as C<8> would identify the device as C<00:08.0>. Virtual domain
+and bus numbers are always 0.
+
+B<NOTE:> This parameter is always parsed as a hexidecimal value.
+
+=item Default Value
+
+None. This parameter is not mandatory. An available B<vslot> will be selected
+if this parameter is not specified.
+
+=back
+
+=back
+
+=head1 Other Parameters and Flags
+
+=over 4
+
+=item B<permissive>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 By default pciback only allows PV guests to write "known safe" values
 into PCI configuration space, likewise QEMU (both qemu-xen and
@@ -46,33 +119,79 @@ more control over the device, which may have security or stability
 implications.  It is recommended to only enable this option for
 trusted VMs under administrator's control.
 
-=item B<msitranslate=BOOLEAN>
+=item Default Value
+
+0
+
+=back
+
+=item B<msitranslate>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 Specifies that MSI-INTx translation should be turned on for the PCI
 device. When enabled, MSI-INTx translation will always enable MSI on
-the PCI device regardless of whether the guest uses INTx or MSI. Some
-device drivers, such as NVIDIA's, detect an inconsistency and do not
+the PCI device regardless of whether the guest uses INTx or MSI.
+
+=item Default Value
+
+Some device drivers, such as NVIDIA's, detect an inconsistency and do not
 function when this option is enabled. Therefore the default is false (0).
 
-=item B<seize=BOOLEAN>
+=back
+
+=item B<seize>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
-Tells B<xl> to automatically attempt to re-assign a device to
-pciback if it is not already assigned.
+Tells L<xl(1)> to automatically attempt to make the device assignable to
+guests if that has not already been done by the B<pci-assignable-add>
+command.
 
-B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
+B<WARNING:> If you set this option, L<xl> will gladly re-assign a critical
 system device, such as a network or a disk controller being used by
 dom0 without confirmation.  Please use with care.
 
-=item B<power_mgmt=BOOLEAN>
+=item Default Value
+
+0
+
+=back
+
+=item B<power_mgmt>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 B<(HVM only)> Specifies that the VM should be able to program the
-D0-D3hot power management states for the PCI device. The default is false (0).
+D0-D3hot power management states for the PCI device.
+
+=item Default Value
+
+0
 
-=item B<rdm_policy=STRING>
+=back
+
+=item B<rdm_policy>=I<STRING>
+
+=over 4
+
+=item Description
 
 B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
-option but just specific to a given device. The default is "relaxed".
+option in L<xl.cfg(5)> but just specific to a given device.
 
-Note: this would override global B<rdm> option.
+B<NOTE>: This overrides the global B<rdm> option.
+
+=item Default Value
+
+"strict"
+
+=back
 
 =back
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:36:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:36:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54526.94812 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJ3-00065e-S9; Tue, 15 Dec 2020 16:36:09 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54526.94812; Tue, 15 Dec 2020 16:36:09 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJ3-00065W-PC; Tue, 15 Dec 2020 16:36:09 +0000
Received: by outflank-mailman (input) for mailman id 54526;
 Tue, 15 Dec 2020 16:36:08 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJ2-00065H-06
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:08 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJ1-0002vV-Vi
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:07 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJ1-0005Z7-Uq
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:07 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2oLFjjHzcFE85jRwJDOm2GKoh6o7/rGil2/PIfhMLUo=; b=KMdbRRfTMQtxhNmTjN5uE/l/MZ
	75gBuKf4oUG9m64vYtCN6zOKl8bLbkF9VyI6cBNcO4PNWyk4vIxkC8IPiDwXAoVoCslPKPgjTg2wT
	l4j0Sbqfg5It2IdvLSmgwsaJCXkR8kWpwgoU26fZs4kt12v0IwZkUOV+MRPZZIW/p1z8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs/man: fix xl(1) documentation for 'pci' operations
Message-Id: <E1kpDJ1-0005Z7-Uq@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:07 +0000

commit 8bc342b043a6838c03cd86039a34e3f8eea1242f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:25 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: fix xl(1) documentation for 'pci' operations
    
    Currently the documentation completely fails to mention the existence of
    PCI_SPEC_STRING. This patch tidies things up, specifically clarifying that
    'pci-assignable-add/remove' take <BDF> arguments where as 'pci-attach/detach'
    take <PCI_SPEC_STRING> arguments (which will be enforced in a subsequent
    patch).
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.1.pod.in | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index eaa72faad6..af31d2b572 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1597,14 +1597,18 @@ List virtual network interfaces for a domain.
 
 =item B<pci-assignable-list>
 
-List all the assignable PCI devices.
+List all the B<BDF> of assignable PCI devices. See
+L<xl-pci-configuration(5)> for more information.
+
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
 =item B<pci-assignable-add> I<BDF>
 
-Make the device at PCI Bus/Device/Function BDF assignable to guests.
+Make the device at B<BDF> assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
+
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
 first be unbound, and the original driver stored so that it can be
@@ -1620,8 +1624,10 @@ being used.
 
 =item B<pci-assignable-remove> [I<-r>] I<BDF>
 
-Make the device at PCI Bus/Device/Function BDF not assignable to
-guests.  This will at least unbind the device from pciback, and
+Make the device at B<BDF> not assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
+
+This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
 option is specified, it will also attempt to re-bind the device to its
 original driver, making it usable by Domain 0 again.  If the device is
@@ -1637,15 +1643,15 @@ As always, this should only be done if you trust the guest, or are
 confident that the particular device you're re-assigning to dom0 will
 cancel all in-flight DMA on FLR.
 
-=item B<pci-attach> I<domain-id> I<BDF>
+=item B<pci-attach> I<domain-id> I<PCI_SPEC_STRING>
 
-Hot-plug a new pass-through pci device to the specified domain.
-B<BDF> is the PCI Bus/Device/Function of the physical device to pass-through.
+Hot-plug a new pass-through pci device to the specified domain. See
+L<xl-pci-configuration(5)> for more information.
 
-=item B<pci-detach> [I<OPTIONS>] I<domain-id> I<BDF>
+=item B<pci-detach> [I<OPTIONS>] I<domain-id> I<PCI_SPEC_STRING>
 
-Hot-unplug a previously assigned pci device from a domain. B<BDF> is the PCI
-Bus/Device/Function of the physical device to be removed from the guest domain.
+Hot-unplug a pci device that was previously passed through to a domain. See
+L<xl-pci-configuration(5)> for more information.
 
 B<OPTIONS>
 
@@ -1660,7 +1666,7 @@ even without guest domain's collaboration.
 
 =item B<pci-list> I<domain-id>
 
-List pass-through pci devices for a domain.
+List the B<BDF> of pci devices passed through to a domain.
 
 =back
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:36:20 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:36:20 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54531.94865 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJE-0006HN-Cb; Tue, 15 Dec 2020 16:36:20 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54531.94865; Tue, 15 Dec 2020 16:36:20 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJE-0006HB-5M; Tue, 15 Dec 2020 16:36:20 +0000
Received: by outflank-mailman (input) for mailman id 54531;
 Tue, 15 Dec 2020 16:36:18 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJC-0006EU-5C
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:18 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJC-0002vp-3n
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:18 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJC-0005aB-2c
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:18 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=N3r9G249liW+R9+ef5lkoHlJgbt8OowWNB1H9WCxQ78=; b=EYVZQQS0xwAyMFALtUnHefiDwp
	6eBvcccgvCme9QD+Ekgo2rXFLlqUKOD+PmCU9iD0IKVeEBEwUbCT8T1LD7KnzkErPuDPPnQ+Rat3A
	rgl/ImBE3QyN6eEDDCqyGRhRfF/sg6aYm8p7O5/wfc6xcIneF2io6YIu+Zw7d+XukVBo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: introduce 'libxl_pci_bdf' in the idl...
Message-Id: <E1kpDJC-0005aB-2c@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:18 +0000

commit 929f23114061a0089e6d63d109cf6a1d03d35c71
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:26 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: introduce 'libxl_pci_bdf' in the idl...
    
    ... and use in 'libxl_device_pci'
    
    This patch is preparatory work for restricting the type passed to functions
    that only require BDF information, rather than passing a 'libxl_device_pci'
    structure which is only partially filled. In this patch only the minimal
    mechanical changes necessary to deal with the structural changes are made.
    Subsequent patches will adjust the code to make better use of the new type.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Acked-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
 tools/golang/xenlight/helpers.gen.go |  77 ++++++++++++------
 tools/golang/xenlight/types.gen.go   |   8 +-
 tools/include/libxl.h                |   6 ++
 tools/libs/light/libxl_dm.c          |   8 +-
 tools/libs/light/libxl_internal.h    |   3 +-
 tools/libs/light/libxl_pci.c         | 148 +++++++++++++++++------------------
 tools/libs/light/libxl_types.idl     |  16 ++--
 tools/libs/util/libxlu_pci.c         |   8 +-
 tools/xl/xl_pci.c                    |   6 +-
 tools/xl/xl_sxp.c                    |   4 +-
 10 files changed, 167 insertions(+), 117 deletions(-)

diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index c8605994e7..b7230f693c 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1999,6 +1999,41 @@ xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)}
  return nil
  }
 
+// NewPciBdf returns an instance of PciBdf initialized with defaults.
+func NewPciBdf() (*PciBdf, error) {
+var (
+x PciBdf
+xc C.libxl_pci_bdf)
+
+C.libxl_pci_bdf_init(&xc)
+defer C.libxl_pci_bdf_dispose(&xc)
+
+if err := x.fromC(&xc); err != nil {
+return nil, err }
+
+return &x, nil}
+
+func (x *PciBdf) fromC(xc *C.libxl_pci_bdf) error {
+ x.Func = byte(xc._func)
+x.Dev = byte(xc.dev)
+x.Bus = byte(xc.bus)
+x.Domain = int(xc.domain)
+
+ return nil}
+
+func (x *PciBdf) toC(xc *C.libxl_pci_bdf) (err error){defer func(){
+if err != nil{
+C.libxl_pci_bdf_dispose(xc)}
+}()
+
+xc._func = C.uint8_t(x.Func)
+xc.dev = C.uint8_t(x.Dev)
+xc.bus = C.uint8_t(x.Bus)
+xc.domain = C.int(x.Domain)
+
+ return nil
+ }
+
 // NewDevicePci returns an instance of DevicePci initialized with defaults.
 func NewDevicePci() (*DevicePci, error) {
 var (
@@ -2014,10 +2049,9 @@ return nil, err }
 return &x, nil}
 
 func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
- x.Func = byte(xc._func)
-x.Dev = byte(xc.dev)
-x.Bus = byte(xc.bus)
-x.Domain = int(xc.domain)
+ if err := x.Bdf.fromC(&xc.bdf);err != nil {
+return fmt.Errorf("converting field Bdf: %v", err)
+}
 x.Vdevfn = uint32(xc.vdevfn)
 x.VfuncMask = uint32(xc.vfunc_mask)
 x.Msitranslate = bool(xc.msitranslate)
@@ -2033,10 +2067,9 @@ if err != nil{
 C.libxl_device_pci_dispose(xc)}
 }()
 
-xc._func = C.uint8_t(x.Func)
-xc.dev = C.uint8_t(x.Dev)
-xc.bus = C.uint8_t(x.Bus)
-xc.domain = C.int(x.Domain)
+if err := x.Bdf.toC(&xc.bdf); err != nil {
+return fmt.Errorf("converting field Bdf: %v", err)
+}
 xc.vdevfn = C.uint32_t(x.Vdevfn)
 xc.vfunc_mask = C.uint32_t(x.VfuncMask)
 xc.msitranslate = C.bool(x.Msitranslate)
@@ -2766,13 +2799,13 @@ if err := x.Nics[i].fromC(&v); err != nil {
 return fmt.Errorf("converting field Nics: %v", err) }
 }
 }
-x.Pcidevs = nil
-if n := int(xc.num_pcidevs); n > 0 {
-cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n]
-x.Pcidevs = make([]DevicePci, n)
-for i, v := range cPcidevs {
-if err := x.Pcidevs[i].fromC(&v); err != nil {
-return fmt.Errorf("converting field Pcidevs: %v", err) }
+x.Pcis = nil
+if n := int(xc.num_pcis); n > 0 {
+cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:n:n]
+x.Pcis = make([]DevicePci, n)
+for i, v := range cPcis {
+if err := x.Pcis[i].fromC(&v); err != nil {
+return fmt.Errorf("converting field Pcis: %v", err) }
 }
 }
 x.Rdms = nil
@@ -2922,13 +2955,13 @@ return fmt.Errorf("converting field Nics: %v", err)
 }
 }
 }
-if numPcidevs := len(x.Pcidevs); numPcidevs > 0 {
-xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs)*C.sizeof_libxl_device_pci))
-xc.num_pcidevs = C.int(numPcidevs)
-cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
-for i,v := range x.Pcidevs {
-if err := v.toC(&cPcidevs[i]); err != nil {
-return fmt.Errorf("converting field Pcidevs: %v", err)
+if numPcis := len(x.Pcis); numPcis > 0 {
+xc.pcis = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcis)*C.sizeof_libxl_device_pci))
+xc.num_pcis = C.int(numPcis)
+cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:numPcis:numPcis]
+for i,v := range x.Pcis {
+if err := v.toC(&cPcis[i]); err != nil {
+return fmt.Errorf("converting field Pcis: %v", err)
 }
 }
 }
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index b4c5df0f2c..bc62ae8ce9 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -707,11 +707,15 @@ ColoCheckpointHost string
 ColoCheckpointPort string
 }
 
-type DevicePci struct {
+type PciBdf struct {
 Func byte
 Dev byte
 Bus byte
 Domain int
+}
+
+type DevicePci struct {
+Bdf PciBdf
 Vdevfn uint32
 VfuncMask uint32
 Msitranslate bool
@@ -896,7 +900,7 @@ CInfo DomainCreateInfo
 BInfo DomainBuildInfo
 Disks []DeviceDisk
 Nics []DeviceNic
-Pcidevs []DevicePci
+Pcis []DevicePci
 Rdms []DeviceRdm
 Dtdevs []DeviceDtdev
 Vfbs []DeviceVfb
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 3433c950f9..1fa4c5806d 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -463,6 +463,12 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
 
+/*
+ * LIBXL_HAVE_PCI_BDF indicates that the 'libxl_pci_bdf' type is defined
+ * is embedded in the 'libxl_device_pci' type.
+ */
+#define LIBXL_HAVE_PCI_BDF 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 3da83259c0..1b951b0920 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -472,10 +472,10 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     for (i = 0; i < d_config->num_pcidevs; i++) {
         unsigned int n, nr_entries;
 
-        seg = d_config->pcidevs[i].domain;
-        bus = d_config->pcidevs[i].bus;
-        devfn = PCI_DEVFN(d_config->pcidevs[i].dev,
-                          d_config->pcidevs[i].func);
+        seg = d_config->pcidevs[i].bdf.domain;
+        bus = d_config->pcidevs[i].bdf.bus;
+        devfn = PCI_DEVFN(d_config->pcidevs[i].bdf.dev,
+                          d_config->pcidevs[i].bdf.func);
         nr_entries = 0;
         rc = libxl__xc_device_get_rdm(gc, 0,
                                       seg, bus, devfn, &nr_entries, &xrdm);
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index c79523ba92..6be7b12e4c 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,10 +4746,11 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
+#define COMPARE_BDF(a, b) ((a)->domain == (b)->domain && \
                            (a)->bus == (b)->bus &&       \
                            (a)->dev == (b)->dev &&       \
                            (a)->func == (b)->func)
+#define COMPARE_PCI(a, b) COMPARE_BDF(&((a)->bdf), &((b)->bdf))
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 74c2196ae3..6b14f0f29e 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -29,10 +29,10 @@ static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pci->domain << 16;
-    value |= (pci->bus & 0xff) << 8;
-    value |= (pci->dev & 0x1f) << 3;
-    value |= (pci->func & 0x7);
+    value = pci->bdf.domain << 16;
+    value |= (pci->bdf.bus & 0xff) << 8;
+    value |= (pci->bdf.dev & 0x1f) << 3;
+    value |= (pci->bdf.func & 0x7);
 
     return value;
 }
@@ -41,10 +41,10 @@ static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pci->domain = domain;
-    pci->bus = bus;
-    pci->dev = dev;
-    pci->func = func;
+    pci->bdf.domain = domain;
+    pci->bdf.bus = bus;
+    pci->bdf.dev = dev;
+    pci->bdf.func = func;
     pci->vdevfn = vdevfn;
 }
 
@@ -54,9 +54,9 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             const libxl_device_pci *pci)
 {
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     if (pci->vdevfn)
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
@@ -250,8 +250,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pci->domain && bus == pci->bus &&
-            pci->dev == dev && pci->func == func) {
+        if (domain == pci->bdf.domain && bus == pci->bdf.bus &&
+            pci->bdf.dev == dev && pci->bdf.func == func) {
             break;
         }
     }
@@ -362,8 +362,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
-                    pci->dev, pci->func);
+    buf = GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus,
+                    pci->bdf.dev, pci->bdf.func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -383,10 +383,10 @@ static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->domain, pci->bus, pci->dev, pci->func,
+                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->domain, pci->bus, pci->dev, pci->func);
+                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 }
 
 
@@ -484,10 +484,10 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pci->domain,
-                           pci->bus,
-                           pci->dev,
-                           pci->func);
+                           pci->bdf.domain,
+                           pci->bdf.bus,
+                           pci->bdf.dev,
+                           pci->bdf.func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -517,7 +517,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pci->domain, pci->bus, pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -525,7 +525,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -533,7 +533,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
 
@@ -544,7 +544,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pci->domain, pci->bus, pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -552,7 +552,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -560,7 +560,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
 
@@ -571,14 +571,14 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pci->domain, pci->bus, pci->dev, pci->func);
+                     pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -587,7 +587,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         ret = ERROR_FAIL;
     }
 
@@ -654,10 +654,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pci->domain
-            && bus == pci->bus
-            && dev == pci->dev
-            && func == pci->func) {
+        if (dom == pci->bdf.domain
+            && bus == pci->bdf.bus
+            && dev == pci->bdf.dev
+            && func == pci->bdf.func) {
             rc = 1;
             goto out;
         }
@@ -683,8 +683,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pci->domain, pci->bus,
-                      pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus,
+                      pci->bdf.dev, pci->bdf.func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -747,10 +747,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pci->domain;
-    bus = pci->bus;
-    dev = pci->dev;
-    func = pci->func;
+    dom = pci->bdf.domain;
+    bus = pci->bdf.bus;
+    dev = pci->bdf.dev;
+    func = pci->bdf.func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -824,8 +824,8 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     /* De-quarantine */
     rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
-            pci->dev, pci->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->bdf.domain, pci->bdf.bus,
+            pci->bdf.dev, pci->bdf.func);
         return ERROR_FAIL;
     }
 
@@ -914,11 +914,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigne
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pci->domain != dom )
+        if ( pci->bdf.domain != dom )
             continue;
-        if ( pci->bus != bus )
+        if ( pci->bdf.bus != bus )
             continue;
-        if ( pci->dev != dev )
+        if ( pci->bdf.dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -967,13 +967,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
     if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pci->domain, pci->bus, pci->dev,
-                         pci->func, pci->vdevfn, pci->msitranslate,
+                         pci->bdf.domain, pci->bdf.bus, pci->bdf.dev,
+                         pci->bdf.func, pci->vdevfn, pci->msitranslate,
                          pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pci->domain,  pci->bus, pci->dev,
-                         pci->func, pci->msitranslate, pci->power_mgmt);
+                         pci->bdf.domain,  pci->bdf.bus, pci->bdf.dev,
+                         pci->bdf.func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1132,10 +1132,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bus, pci->dev, pci->func);
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pci->domain,
-                           pci->bus, pci->dev, pci->func);
+                           "%04x:%02x:%02x.%01x", pci->bdf.domain,
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
                                PCI_SLOT(pci->vdevfn),
@@ -1223,7 +1223,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bus, pci->dev, pci->func);
+                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1314,8 +1314,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
-                           pci->bus, pci->dev, pci->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1355,8 +1355,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
-                                pci->bus, pci->dev, pci->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
+                                pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1527,7 +1527,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pci->domain, pci->bus, pci->dev, pci->func,
+                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
@@ -1545,7 +1545,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 
     if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         rc = ERROR_FAIL;
         goto out;
     }
@@ -1553,7 +1553,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
-    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
+    libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
@@ -1634,13 +1634,13 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
         pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pci->func);
+        pfunc_mask = (1 << pci->bdf.func);
     }
 
     for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->func = i;
+                pci->bdf.func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 /* if not passing through multiple devices in a block make
@@ -1672,7 +1672,7 @@ static void device_pci_add_done(libxl__egc *egc,
         LOGD(ERROR, domid,
              "libxl__device_pci_add  failed for "
              "PCI device %x:%x:%x.%x (rc %d)",
-             pci->domain, pci->bus, pci->dev, pci->func,
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
              rc);
         pci_info_xs_remove(gc, pci, "domid");
     }
@@ -1741,8 +1741,8 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
-                     pci->bus, pci->dev, pci->func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->bdf.domain,
+                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
@@ -1856,8 +1856,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
-                                     pci->bus, pci->dev, pci->func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
+                                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -1892,8 +1892,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
-                               pci->bus, pci->dev, pci->func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
+                               pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1957,7 +1957,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bus, pci->dev, pci->func);
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2026,7 +2026,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bus, pci->dev, pci->func);
+                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2077,7 +2077,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
+         PCI_PT_QDEV_ID, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2110,7 +2110,7 @@ static void pci_remove_detached(libxl__egc *egc,
 
     /* don't do multiple resets while some functions are still passed through */
     if ((pci->vdevfn & 0x7) == 0) {
-        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
+        libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     }
 
     if (!isstubdom) {
@@ -2198,7 +2198,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
         }
         pci->vfunc_mask &= prs->pfunc_mask;
     } else {
-        prs->pfunc_mask = (1 << pci->func);
+        prs->pfunc_mask = (1 << pci->bdf.func);
     }
 
     rc = 0;
@@ -2226,7 +2226,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->func = i;
+                pci->bdf.func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 pci->vdevfn = orig_vdev;
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 05324736b7..21a2cf5c1c 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -770,18 +770,22 @@ libxl_device_nic = Struct("device_nic", [
     ("colo_checkpoint_port", string)
     ])
 
+libxl_pci_bdf = Struct("pci_bdf", [
+    ("func", uint8),
+    ("dev", uint8),
+    ("bus", uint8),
+    ("domain", integer),
+    ])
+
 libxl_device_pci = Struct("device_pci", [
-    ("func",      uint8),
-    ("dev",       uint8),
-    ("bus",       uint8),
-    ("domain",    integer),
-    ("vdevfn",    uint32),
+    ("bdf", libxl_pci_bdf),
+    ("vdevfn", uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
     ("power_mgmt", bool),
     ("permissive", bool),
     ("seize", bool),
-    ("rdm_policy",      libxl_rdm_reserve_policy),
+    ("rdm_policy", libxl_rdm_reserve_policy),
     ])
 
 libxl_device_rdm = Struct("device_rdm", [
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 1d38fffce3..5c107f2642 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -27,10 +27,10 @@ static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                            unsigned int bus, unsigned int dev,
                            unsigned int func, unsigned int vdevfn)
 {
-    pci->domain = domain;
-    pci->bus = bus;
-    pci->dev = dev;
-    pci->func = func;
+    pci->bdf.domain = domain;
+    pci->bdf.bus = bus;
+    pci->bdf.dev = dev;
+    pci->bdf.func = func;
     pci->vdevfn = vdevfn;
     return 0;
 }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index f71498cbb5..b6dc7c2840 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -34,7 +34,8 @@ static void pcilist(uint32_t domid)
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
-               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
+               pcis[i].bdf.func);
     }
     libxl_device_pci_list_free(pcis, num);
 }
@@ -163,7 +164,8 @@ static void pciassignable_list(void)
         return;
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
-               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
+               pcis[i].bdf.func);
     }
     libxl_device_pci_assignable_list_free(pcis, num);
 }
diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c
index 359a001570..dc49fb7d50 100644
--- a/tools/xl/xl_sxp.c
+++ b/tools/xl/xl_sxp.c
@@ -194,8 +194,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh)
         fprintf(fh, "\t(device\n");
         fprintf(fh, "\t\t(pci\n");
         fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
-               d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
-               d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
+               d_config->pcidevs[i].bdf.domain, d_config->pcidevs[i].bdf.bus,
+               d_config->pcidevs[i].bdf.dev, d_config->pcidevs[i].bdf.func,
                d_config->pcidevs[i].vdevfn);
         fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n",
                d_config->pcidevs[i].msitranslate,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:36:30 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:36:30 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54540.94916 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJO-0006bm-B5; Tue, 15 Dec 2020 16:36:30 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54540.94916; Tue, 15 Dec 2020 16:36:30 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJO-0006bZ-3b; Tue, 15 Dec 2020 16:36:30 +0000
Received: by outflank-mailman (input) for mailman id 54540;
 Tue, 15 Dec 2020 16:36:28 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJM-0006Xe-8H
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:28 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJM-0002w7-7H
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:28 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJM-0005bN-61
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:28 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Chl4N8VoW8w7nKRM/GQvHJuIw3EwkGdJd6+jNQFEEOU=; b=cklR1lctZzEN2g9mHyiyAn3DTt
	p3q9fDMVa7obReWJyXDx8prXjMVlPjm2kUqb333us6Zc8/ZKdQ/V1my70Mtkr4oAnxAzt62TCEsnb
	ThN2FBD5sQqzMe0u1gpQDVjNGpKh64HVHWPrIupBaMY3MkPFYzBHCml25XFWg2h2oNTo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxlu: introduce xlu_pci_parse_spec_string()
Message-Id: <E1kpDJM-0005bN-61@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:28 +0000

commit 96ed6ff29741df820217b6b744eb0fa2d76b50f3
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:27 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxlu: introduce xlu_pci_parse_spec_string()
    
    This patch largely re-writes the code to parse a PCI_SPEC_STRING and enters
    it via the newly introduced function. The new parser also deals with 'bdf'
    and 'vslot' as non-positional paramaters, as per the documentation in
    xl-pci-configuration(5).
    
    The existing xlu_pci_parse_bdf() function remains, but now strictly parses
    BDF values. Some existing callers of xlu_pci_parse_bdf() are
    modified to call xlu_pci_parse_spec_string() as per the documentation in xl(1).
    
    NOTE: Usage text in xl_cmdtable.c and error messages are also modified
          appropriately.
          As a side-effect this patch also fixes a bug where using '*' to specify
          all functions would lead to an assertion failure at the end of
          xlu_pci_parse_bdf().
    
    Fixes: d25cc3ec93eb ("libxl: workaround gcc 10.2 maybe-uninitialized warning")
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxlutil.h    |   8 +-
 tools/libs/util/libxlu_pci.c | 354 +++++++++++++++++++++++--------------------
 tools/xl/xl_cmdtable.c       |   4 +-
 tools/xl/xl_parse.c          |   4 +-
 tools/xl/xl_pci.c            |  37 +++--
 5 files changed, 220 insertions(+), 187 deletions(-)

diff --git a/tools/include/libxlutil.h b/tools/include/libxlutil.h
index 92e35c5462..cdd6aab4f8 100644
--- a/tools/include/libxlutil.h
+++ b/tools/include/libxlutil.h
@@ -108,10 +108,16 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs,
    * resulting disk struct is used with libxl.
    */
 
+/*
+ * PCI BDF
+ */
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str);
+
 /*
  * PCI specification parsing
  */
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str);
+int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pci,
+                              const char *str);
 
 /*
  * RDM parsing
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 5c107f2642..a8b6ce5427 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -1,5 +1,7 @@
 #define _GNU_SOURCE
 
+#include <ctype.h>
+
 #include "libxlu_internal.h"
 #include "libxlu_disk_l.h"
 #include "libxlu_disk_i.h"
@@ -9,185 +11,213 @@
 #define XLU__PCI_ERR(_c, _x, _a...) \
     if((_c) && (_c)->report) fprintf((_c)->report, _x, ##_a)
 
-static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
+static int parse_bdf(libxl_pci_bdf *bdfp, uint32_t *vfunc_maskp,
+                     const char *str, const char **endp)
 {
-    unsigned long ret;
-    char *end;
-
-    ret = strtoul(str, &end, 16);
-    if ( end == str || *end != '\0' )
-        return -1;
-    if ( ret & ~mask )
-        return -1;
-    *val = (unsigned int)ret & mask;
+    const char *ptr = str;
+    unsigned int colons = 0;
+    unsigned int domain, bus, dev, func;
+    int n;
+
+    /* Count occurrences of ':' to detrmine presence/absence of the 'domain' */
+    while (isxdigit(*ptr) || *ptr == ':') {
+        if (*ptr == ':')
+            colons++;
+        ptr++;
+    }
+
+    ptr = str;
+    switch (colons) {
+    case 1:
+        domain = 0;
+        if (sscanf(ptr, "%x:%x.%n", &bus, &dev, &n) != 2)
+            return ERROR_INVAL;
+        break;
+    case 2:
+        if (sscanf(ptr, "%x:%x:%x.%n", &domain, &bus, &dev, &n) != 3)
+            return ERROR_INVAL;
+        break;
+    default:
+        return ERROR_INVAL;
+    }
+
+    if (domain > 0xffff || bus > 0xff || dev > 0x1f)
+        return ERROR_INVAL;
+
+    ptr += n;
+    if (*ptr == '*') {
+        if (!vfunc_maskp)
+            return ERROR_INVAL;
+        *vfunc_maskp = LIBXL_PCI_FUNC_ALL;
+        func = 0;
+        ptr++;
+    } else {
+        if (sscanf(ptr, "%x%n", &func, &n) != 1)
+            return ERROR_INVAL;
+        if (func > 7)
+            return ERROR_INVAL;
+        if (vfunc_maskp)
+            *vfunc_maskp = 1;
+        ptr += n;
+    }
+
+    bdfp->domain = domain;
+    bdfp->bus = bus;
+    bdfp->dev = dev;
+    bdfp->func = func;
+
+    if (endp)
+        *endp = ptr;
+
     return 0;
 }
 
-static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
-                           unsigned int bus, unsigned int dev,
-                           unsigned int func, unsigned int vdevfn)
+static int parse_vslot(uint32_t *vdevfnp, const char *str, const char **endp)
 {
-    pci->bdf.domain = domain;
-    pci->bdf.bus = bus;
-    pci->bdf.dev = dev;
-    pci->bdf.func = func;
-    pci->vdevfn = vdevfn;
+    const char *ptr = str;
+    unsigned int val;
+    int n;
+
+    if (sscanf(ptr, "%x%n", &val, &n) != 1)
+        return ERROR_INVAL;
+
+    if (val > 0x1f)
+        return ERROR_INVAL;
+
+    ptr += n;
+
+    *vdevfnp = val << 3;
+
+    if (endp)
+        *endp = ptr;
+
     return 0;
 }
 
-#define STATE_DOMAIN    0
-#define STATE_BUS       1
-#define STATE_DEV       2
-#define STATE_FUNC      3
-#define STATE_VSLOT     4
-#define STATE_OPTIONS_K 6
-#define STATE_OPTIONS_V 7
-#define STATE_TERMINAL  8
-#define STATE_TYPE      9
-#define STATE_RDM_STRATEGY      10
-#define STATE_RESERVE_POLICY    11
-#define INVALID         0xffffffff
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
+static int parse_key_val(char **keyp, char**valp, const char *str,
+                         const char **endp)
 {
-    unsigned state = STATE_DOMAIN;
-    unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
-    char *buf2, *tok, *ptr, *end, *optkey = NULL;
+    const char *ptr = str;
+    char *key, *val;
+
+    while (*ptr != '=' && *ptr != '\0')
+        ptr++;
 
-    if ( NULL == (buf2 = ptr = strdup(str)) )
+    if (*ptr == '\0')
+        return ERROR_INVAL;
+
+    key = strndup(str, ptr - str);
+    if (!key)
         return ERROR_NOMEM;
 
-    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
-        switch(state) {
-        case STATE_DOMAIN:
-            if ( *ptr == ':' ) {
-                state = STATE_BUS;
-                *ptr = '\0';
-                if ( hex_convert(tok, &dom, 0xffff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_BUS:
-            if ( *ptr == ':' ) {
-                state = STATE_DEV;
-                *ptr = '\0';
-                if ( hex_convert(tok, &bus, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }else if ( *ptr == '.' ) {
-                state = STATE_FUNC;
-                *ptr = '\0';
-                if ( dom & ~0xff )
-                    goto parse_error;
-                bus = dom;
-                dom = 0;
-                if ( hex_convert(tok, &dev, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_DEV:
-            if ( *ptr == '.' ) {
-                state = STATE_FUNC;
-                *ptr = '\0';
-                if ( hex_convert(tok, &dev, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_FUNC:
-            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
-                switch( *ptr ) {
-                case '\0':
-                    state = STATE_TERMINAL;
-                    break;
-                case '@':
-                    state = STATE_VSLOT;
-                    break;
-                case ',':
-                    state = STATE_OPTIONS_K;
-                    break;
-                }
-                *ptr = '\0';
-                if ( !strcmp(tok, "*") ) {
-                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
-                }else{
-                    if ( hex_convert(tok, &func, 0x7) )
-                        goto parse_error;
-                    pci->vfunc_mask = (1 << 0);
-                }
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_VSLOT:
-            if ( *ptr == '\0' || *ptr == ',' ) {
-                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
-                *ptr = '\0';
-                if ( hex_convert(tok, &vslot, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_OPTIONS_K:
-            if ( *ptr == '=' ) {
-                state = STATE_OPTIONS_V;
-                *ptr = '\0';
-                optkey = tok;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_OPTIONS_V:
-            if ( *ptr == ',' || *ptr == '\0' ) {
-                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
-                *ptr = '\0';
-                if ( !strcmp(optkey, "msitranslate") ) {
-                    pci->msitranslate = atoi(tok);
-                }else if ( !strcmp(optkey, "power_mgmt") ) {
-                    pci->power_mgmt = atoi(tok);
-                }else if ( !strcmp(optkey, "permissive") ) {
-                    pci->permissive = atoi(tok);
-                }else if ( !strcmp(optkey, "seize") ) {
-                    pci->seize = atoi(tok);
-                } else if (!strcmp(optkey, "rdm_policy")) {
-                    if (!strcmp(tok, "strict")) {
-                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
-                    } else if (!strcmp(tok, "relaxed")) {
-                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
-                    } else {
-                        XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
-                                          " policy: 'strict' or 'relaxed'.",
-                                     tok);
-                        goto parse_error;
-                    }
-                } else {
-                    XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey);
-                }
-                tok = ptr + 1;
-            }
-        default:
-            break;
+    str = ++ptr; /* skip '=' */
+    while (*ptr != ',' && *ptr != '\0')
+        ptr++;
+
+    val = strndup(str, ptr - str);
+    if (!val) {
+        free(key);
+        return ERROR_NOMEM;
+    }
+
+    if (*ptr == ',')
+        ptr++;
+
+    *keyp = key;
+    *valp = val;
+    *endp = ptr;
+
+    return 0;
+}
+
+static int parse_rdm_policy(XLU_Config *cfg, libxl_rdm_reserve_policy *policy,
+                            const char *str)
+{
+    int ret = libxl_rdm_reserve_policy_from_string(str, policy);
+
+    if (ret)
+        XLU__PCI_ERR(cfg, "Unknown RDM policy: %s", str);
+
+    return ret;
+}
+
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str)
+{
+    return parse_bdf(bdf, NULL, str, NULL);
+}
+
+int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
+                              const char *str)
+{
+    const char *ptr = str;
+    bool bdf_present = false;
+    int ret;
+
+    /* Attempt to parse 'bdf' as positional parameter */
+    ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, ptr, &ptr);
+    if (!ret) {
+        bdf_present = true;
+
+        /* Check whether 'vslot' if present */
+        if (*ptr == '@') {
+            ret = parse_vslot(&pcidev->vdevfn, ++ptr, &ptr);
+            if (ret)
+                return ret;
         }
+        if (*ptr == ',')
+            ptr++;
+        else if (*ptr != '\0')
+            return ERROR_INVAL;
     }
 
-    if ( tok != ptr || state != STATE_TERMINAL )
-        goto parse_error;
+    /* Parse the rest as 'key=val' pairs */
+    while (*ptr != '\0') {
+        char *key, *val;
 
-    assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
+        ret = parse_key_val(&key, &val, ptr, &ptr);
+        if (ret)
+            return ret;
 
-    /* Just a pretty way to fill in the values */
-    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
+        if (!strcmp(key, "bdf")) {
+            ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, val, NULL);
+            bdf_present = !ret;
+        } else if (!strcmp(key, "vslot")) {
+            ret = parse_vslot(&pcidev->vdevfn, val, NULL);
+        } else if (!strcmp(key, "permissive")) {
+            pcidev->permissive = atoi(val);
+        } else if (!strcmp(key, "msitranslate")) {
+            pcidev->msitranslate = atoi(val);
+        } else if (!strcmp(key, "seize")) {
+            pcidev->seize= atoi(val);
+        } else if (!strcmp(key, "power_mgmt")) {
+            pcidev->power_mgmt = atoi(val);
+        } else if (!strcmp(key, "rdm_policy")) {
+            ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
+        } else {
+            XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
+            ret = ERROR_INVAL;
+        }
 
-    free(buf2);
+        free(key);
+        free(val);
 
-    return 0;
+        if (ret)
+            return ret;
+    }
 
-parse_error:
-    free(buf2);
-    return ERROR_INVAL;
+    if (!bdf_present)
+        return ERROR_INVAL;
+
+    return 0;
 }
 
 int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 {
+#define STATE_TYPE           0
+#define STATE_RDM_STRATEGY   1
+#define STATE_RESERVE_POLICY 2
+#define STATE_TERMINAL       3
+
     unsigned state = STATE_TYPE;
     char *buf2, *tok, *ptr, *end;
 
@@ -227,15 +257,8 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
             if (*ptr == ',' || *ptr == '\0') {
                 state = *ptr == ',' ? STATE_TYPE : STATE_TERMINAL;
                 *ptr = '\0';
-                if (!strcmp(tok, "strict")) {
-                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
-                } else if (!strcmp(tok, "relaxed")) {
-                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
-                } else {
-                    XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s",
-                                 tok);
+                if (!parse_rdm_policy(cfg, &rdm->policy, tok))
                     goto parse_error;
-                }
                 tok = ptr + 1;
             }
         default:
@@ -253,6 +276,11 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 parse_error:
     free(buf2);
     return ERROR_INVAL;
+
+#undef STATE_TYPE
+#undef STATE_RDM_STRATEGY
+#undef STATE_RESERVE_POLICY
+#undef STATE_TERMINAL
 }
 
 /*
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 6ab5e47da3..30e17a2848 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -90,12 +90,12 @@ struct cmd_spec cmd_table[] = {
     { "pci-attach",
       &main_pciattach, 0, 1,
       "Insert a new pass-through pci device",
-      "<Domain> <BDF> [Virtual Slot]",
+      "<Domain> <PCI_SPEC_STRING>",
     },
     { "pci-detach",
       &main_pcidetach, 0, 1,
       "Remove a domain's pass-through pci device",
-      "<Domain> <BDF>",
+      "<Domain> <PCI_SPEC_STRING>",
     },
     { "pci-list",
       &main_pcilist, 0, 0,
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 4ebf39620a..867e4d068a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1487,10 +1487,10 @@ void parse_config_data(const char *config_source,
              * the global policy by default.
              */
             pci->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_bdf(config, pci, buf);
+            e = xlu_pci_parse_spec_string(config, pci, buf);
             if (e) {
                 fprintf(stderr,
-                        "unable to parse PCI BDF `%s' for passthrough\n",
+                        "unable to parse PCI_SPEC_STRING `%s' for passthrough\n",
                         buf);
                 exit(-e);
             }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index b6dc7c2840..9c24496cb2 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -55,7 +55,7 @@ int main_pcilist(int argc, char **argv)
     return 0;
 }
 
-static int pcidetach(uint32_t domid, const char *bdf, int force)
+static int pcidetach(uint32_t domid, const char *spec_string, int force)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -66,8 +66,9 @@ static int pcidetach(uint32_t domid, const char *bdf, int force)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
+        fprintf(stderr, "pci-detach: malformed PCI_SPEC_STRING \"%s\"\n",
+                spec_string);
         exit(2);
     }
     if (force) {
@@ -89,7 +90,7 @@ int main_pcidetach(int argc, char **argv)
     uint32_t domid;
     int opt;
     int force = 0;
-    const char *bdf = NULL;
+    const char *spec_string = NULL;
 
     SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
     case 'f':
@@ -98,15 +99,15 @@ int main_pcidetach(int argc, char **argv)
     }
 
     domid = find_domain(argv[optind]);
-    bdf = argv[optind + 1];
+    spec_string = argv[optind + 1];
 
-    if (pcidetach(domid, bdf, force))
+    if (pcidetach(domid, spec_string, force))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciattach(uint32_t domid, const char *bdf, const char *vs)
+static int pciattach(uint32_t domid, const char *spec_string)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -117,8 +118,9 @@ static int pciattach(uint32_t domid, const char *bdf, const char *vs)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
+        fprintf(stderr, "pci-attach: malformed PCI_SPEC_STRING \"%s\"\n",
+                spec_string);
         exit(2);
     }
 
@@ -135,19 +137,16 @@ int main_pciattach(int argc, char **argv)
 {
     uint32_t domid;
     int opt;
-    const char *bdf = NULL, *vs = NULL;
+    const char *spec_string = NULL;
 
     SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
         /* No options */
     }
 
     domid = find_domain(argv[optind]);
-    bdf = argv[optind + 1];
-
-    if (optind + 1 < argc)
-        vs = argv[optind + 2];
+    spec_string = argv[optind + 1];
 
-    if (pciattach(domid, bdf, vs))
+    if (pciattach(domid, spec_string))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
@@ -193,8 +192,8 @@ static int pciassignable_add(const char *bdf, int rebind)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+        fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
@@ -235,8 +234,8 @@ static int pciassignable_remove(const char *bdf, int rebind)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+        fprintf(stderr, "pci-assignable-remove: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:36:40 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:36:40 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54553.94967 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJY-0006yK-IT; Tue, 15 Dec 2020 16:36:40 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54553.94967; Tue, 15 Dec 2020 16:36:40 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJY-0006yB-DP; Tue, 15 Dec 2020 16:36:40 +0000
Received: by outflank-mailman (input) for mailman id 54553;
 Tue, 15 Dec 2020 16:36:38 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJW-0006sr-Be
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:38 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJW-0002wU-AA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:38 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJW-0005cJ-9Q
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:38 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JiIUd2pS15JXp34iHvcAeouqT19x7t7am+e8aaREEIE=; b=lBHEkQcTz7UfjNIQqTRii+PCsV
	txA4dXn5+V9tAm1YF5CfM/2JXASEOmIjnfqqYBhQ1zKJ06W6tFVPAKaPitpoUi2jSJXiQPyTEKcKf
	TO0OiyC/15efAKZGJ75vb2YTPgfswvtx4uIpgvKkgrYmar98ZYCMBGKYGHzsz3YO7FGA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs/man: modify xl(1) in preparation for naming of assignable devices
Message-Id: <E1kpDJW-0005cJ-9Q@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:38 +0000

commit f73c5dd56d78008e4b9c1fd7bf26b66e0afb8b54
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:28 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: modify xl(1) in preparation for naming of assignable devices
    
    A subsequent patch will introduce code to allow a name to be specified to
    'xl pci-assignable-add' such that the assignable device may be referred to
    by than name in subsequent operations.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.1.pod.in | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index af31d2b572..f4779d8fd6 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1595,19 +1595,23 @@ List virtual network interfaces for a domain.
 
 =over 4
 
-=item B<pci-assignable-list>
+=item B<pci-assignable-list> [I<-n>]
 
 List all the B<BDF> of assignable PCI devices. See
-L<xl-pci-configuration(5)> for more information.
+L<xl-pci-configuration(5)> for more information. If the -n option is
+specified then any name supplied when the device was made assignable
+will also be displayed.
 
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
-=item B<pci-assignable-add> I<BDF>
+=item B<pci-assignable-add> [I<-n NAME>] I<BDF>
 
 Make the device at B<BDF> assignable to guests. See
-L<xl-pci-configuration(5)> for more information.
+L<xl-pci-configuration(5)> for more information. If the -n option is
+supplied then the assignable device entry will the named with the
+given B<NAME>.
 
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
@@ -1622,10 +1626,11 @@ not to do this on a device critical to domain 0's operation, such as
 storage controllers, network interfaces, or GPUs that are currently
 being used.
 
-=item B<pci-assignable-remove> [I<-r>] I<BDF>
+=item B<pci-assignable-remove> [I<-r>] I<BDF>|I<NAME>
 
-Make the device at B<BDF> not assignable to guests. See
-L<xl-pci-configuration(5)> for more information.
+Make a device non-assignable to guests. The device may be identified
+either by its B<BDF> or the B<NAME> supplied when the device was made
+assignable. See L<xl-pci-configuration(5)> for more information.
 
 This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:36:49 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:36:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54564.95019 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJh-0007JH-GM; Tue, 15 Dec 2020 16:36:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54564.95019; Tue, 15 Dec 2020 16:36:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJh-0007J7-8R; Tue, 15 Dec 2020 16:36:49 +0000
Received: by outflank-mailman (input) for mailman id 54564;
 Tue, 15 Dec 2020 16:36:48 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJg-0007Gt-EE
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:48 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJg-0002wX-D9
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:48 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJg-0005d7-CG
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:48 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=MaNRvYrEW+IXTxl7ePn2m+PuBFr64BxsNdFrIClpIq4=; b=q4rieC2flGgqQow0LguVRaf4kI
	IUUDS6JliTYf1axOGiMIrmxJhe0I971Ibuj451sPbwbPdIl4qTP2r80wkiOtKQYaePhRQzAL+f2sJ
	Csv20dUcsVVZPjNRSpMOZqu1KfWJP1el+4ltDyAnR6KABXwMmnkmDy3IFX5CXRUNUbjI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: convert internal functions in libxl_pci.c...
Message-Id: <E1kpDJg-0005d7-CG@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:48 +0000

commit 66c2fbc6e82b1aa7b9f0fb37eecf93983c348058
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:29 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: convert internal functions in libxl_pci.c...
    
    ... to use 'libx_pci_bdf' where appropriate.
    
    No API change.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 192 +++++++++++++++++++++++--------------------
 1 file changed, 103 insertions(+), 89 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 6b14f0f29e..448fe96951 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,26 +25,33 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pci_encode_bdf(libxl_device_pci *pci)
+static unsigned int pci_encode_bdf(libxl_pci_bdf *pcibdf)
 {
     unsigned int value;
 
-    value = pci->bdf.domain << 16;
-    value |= (pci->bdf.bus & 0xff) << 8;
-    value |= (pci->bdf.dev & 0x1f) << 3;
-    value |= (pci->bdf.func & 0x7);
+    value = pcibdf->domain << 16;
+    value |= (pcibdf->bus & 0xff) << 8;
+    value |= (pcibdf->dev & 0x1f) << 3;
+    value |= (pcibdf->func & 0x7);
 
     return value;
 }
 
+static void pcibdf_struct_fill(libxl_pci_bdf *pcibdf, unsigned int domain,
+                               unsigned int bus, unsigned int dev,
+                               unsigned int func)
+{
+    pcibdf->domain = domain;
+    pcibdf->bus = bus;
+    pcibdf->dev = dev;
+    pcibdf->func = func;
+}
+
 static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pci->bdf.domain = domain;
-    pci->bdf.bus = bus;
-    pci->bdf.dev = dev;
-    pci->bdf.func = func;
+    pcibdf_struct_fill(&pci->bdf, domain, bus, dev, func);
     pci->vdevfn = vdevfn;
 }
 
@@ -350,8 +357,8 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num,
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
-static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
-                           libxl_device_pci *pci)
+static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
+                           libxl_pci_bdf *pcibdf)
 {
     int rc, fd;
     char *buf;
@@ -362,8 +369,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus,
-                    pci->bdf.dev, pci->bdf.func);
+    buf = GCSPRINTF(PCI_BDF, pcibdf->domain, pcibdf->bus,
+                    pcibdf->dev, pcibdf->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -378,22 +385,22 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
 
 #define PCI_INFO_PATH "/libxl/pci"
 
-static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+static char *pci_info_xs_path(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node)
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
 }
 
 
-static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node, const char *val)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
     int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
 
     if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
@@ -401,18 +408,18 @@ static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
     return rc;
 }
 
-static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+static char *pci_info_xs_read(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
 
     return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                                const char *node)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
@@ -451,9 +458,9 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         new = pcis + *num;
 
         libxl_device_pci_init(new);
-        pci_struct_fill(new, dom, bus, dev, func, 0);
+        pcibdf_struct_fill(&new->bdf, dom, bus, dev, func);
 
-        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
+        if (pci_info_xs_read(gc, &new->bdf, "domid")) /* already assigned */
             continue;
 
         (*num)++;
@@ -477,17 +484,17 @@ void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pci->bdf.domain,
-                           pci->bdf.bus,
-                           pci->bdf.dev,
-                           pci->bdf.func);
+                           pcibdf->domain,
+                           pcibdf->bus,
+                           pcibdf->dev,
+                           pcibdf->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -501,7 +508,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -639,8 +646,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for pci's BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
+/* Scan through /sys/.../pciback/slots looking for BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     FILE *f;
     int rc = 0;
@@ -654,10 +661,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pci->bdf.domain
-            && bus == pci->bdf.bus
-            && dev == pci->bdf.dev
-            && func == pci->bdf.func) {
+        if (dom == pcibdf->domain
+            && bus == pcibdf->bus
+            && dev == pcibdf->dev
+            && func == pcibdf->func) {
             rc = 1;
             goto out;
         }
@@ -667,7 +674,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     char * spath;
     int rc;
@@ -683,8 +690,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pci->bdf.domain, pci->bdf.bus,
-                      pci->bdf.dev, pci->bdf.func);
+                      pcibdf->domain, pcibdf->bus,
+                      pcibdf->dev, pcibdf->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -695,40 +702,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_assign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     int rc;
 
-    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pcibdf)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pci) < 0 ) {
+                             pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcibdf) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pcibdf, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pcibdf) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pci) < 0 ) {
+                             pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -736,9 +743,9 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-static int libxl__device_pci_assignable_add(libxl__gc *gc,
-                                            libxl_device_pci *pci,
-                                            int rebind)
+static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
+                                         libxl_pci_bdf *pcibdf,
+                                         int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     unsigned dom, bus, dev, func;
@@ -747,10 +754,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pci->bdf.domain;
-    bus = pci->bdf.bus;
-    dev = pci->bdf.dev;
-    func = pci->bdf.func;
+    dom = pcibdf->domain;
+    bus = pcibdf->bus;
+    dev = pcibdf->dev;
+    func = pcibdf->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -760,7 +767,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pci);
+    rc = pciback_dev_is_assigned(gc, pcibdf);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
@@ -770,7 +777,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pcibdf, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -779,9 +786,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_info_xs_write(gc, pci, "driver_path", driver_path);
+            pci_info_xs_write(gc, pcibdf, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
+                     pci_info_xs_read(gc, pcibdf, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -789,10 +796,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_info_xs_remove(gc, pci, "driver_path");
+        pci_info_xs_remove(gc, pcibdf, "driver_path");
     }
 
-    if ( pciback_dev_assign(gc, pci) ) {
+    if ( pciback_dev_assign(gc, pcibdf) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
@@ -803,7 +810,7 @@ quarantine:
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -813,33 +820,33 @@ quarantine:
     return 0;
 }
 
-static int libxl__device_pci_assignable_remove(libxl__gc *gc,
-                                               libxl_device_pci *pci,
-                                               int rebind)
+static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
+                                            libxl_pci_bdf *pcibdf,
+                                            int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc;
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->bdf.domain, pci->bdf.bus,
-            pci->bdf.dev, pci->bdf.func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcibdf->domain,
+            pcibdf->bus, pcibdf->dev, pcibdf->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pcibdf)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pci);
+        pciback_dev_unassign(gc, pcibdf);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_info_xs_read(gc, pci, "driver_path");
+    driver_path = pci_info_xs_read(gc, pcibdf, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -847,12 +854,12 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pci) < 0 ) {
+                                 pcibdf) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_info_xs_remove(gc, pci, "driver_path");
+            pci_info_xs_remove(gc, pcibdf, "driver_path");
         }
     } else {
         if ( rebind ) {
@@ -870,7 +877,7 @@ int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
+    rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, rebind);
 
     GC_FREE;
     return rc;
@@ -883,7 +890,7 @@ int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
+    rc = libxl__pci_bdf_assignable_remove(gc, &pci->bdf, rebind);
 
     GC_FREE;
     return rc;
@@ -1385,7 +1392,7 @@ static void pci_add_dm_done(libxl__egc *egc,
     /* Don't restrict writes to the PCI config space from this VM */
     if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             pci) < 0 ) {
+                             &pci->bdf) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1401,7 +1408,8 @@ out_no_irq:
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(&pci->bdf),
+                             flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1480,17 +1488,21 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
+static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
 {
     libxl_device_pci *pcis;
-    int num;
-    bool assignable;
+    int num, i;
 
     pcis = libxl_device_pci_assignable_list(ctx, &num);
-    assignable = is_pci_in_array(pcis, num, pci);
+
+    for (i = 0; i < num; i++) {
+        if (COMPARE_BDF(pcibdf, &pcis[i].bdf))
+            break;
+    }
+
     libxl_device_pci_assignable_list_free(pcis, num);
 
-    return assignable;
+    return i < num;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1523,7 +1535,8 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->callback = device_pci_add_stubdom_done;
 
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
+        rc = xc_test_assign_device(ctx->xch, domid,
+                                   pci_encode_bdf(&pci->bdf));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
@@ -1537,20 +1550,20 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
-        rc = libxl__device_pci_assignable_add(gc, pci, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
+        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, 1);
         if ( rc )
             goto out;
     }
 
-    if (!libxl_pci_assignable(ctx, pci)) {
+    if (!is_bdf_assignable(ctx, &pci->bdf)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
              pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         rc = ERROR_FAIL;
         goto out;
     }
 
-    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
+    rc = pci_info_xs_write(gc, &pci->bdf, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
     libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
@@ -1674,7 +1687,7 @@ static void device_pci_add_done(libxl__egc *egc,
              "PCI device %x:%x:%x.%x (rc %d)",
              pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
              rc);
-        pci_info_xs_remove(gc, pci, "domid");
+        pci_info_xs_remove(gc, &pci->bdf, "domid");
     }
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -2114,7 +2127,8 @@ static void pci_remove_detached(libxl__egc *egc,
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
+        rc = xc_deassign_device(CTX->xch, domid,
+                                pci_encode_bdf(&pci->bdf));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
@@ -2243,7 +2257,7 @@ out:
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
 
-    if (!rc) pci_info_xs_remove(gc, pci, "domid");
+    if (!rc) pci_info_xs_remove(gc, &pci->bdf, "domid");
 
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:37:00 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:37:00 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54579.95072 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJs-0007n9-DD; Tue, 15 Dec 2020 16:37:00 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54579.95072; Tue, 15 Dec 2020 16:37:00 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDJs-0007mh-5n; Tue, 15 Dec 2020 16:37:00 +0000
Received: by outflank-mailman (input) for mailman id 54579;
 Tue, 15 Dec 2020 16:36:58 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJq-0007iK-Hu
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:58 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJq-0002wa-GB
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:58 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDJq-0005eI-FO
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:36:58 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aRAlSD+rBo6dx9wwafm1OGYJFS/kVBq/cjKtpoxTBMU=; b=cZ5Wo6/n3OTH5g+mIUA7fZb3eM
	7MLzjnD1Tv/ifHCgD9JVor7pc7etfUKjmie4/NyOsXSSFNVZs9PGZfC0rgoybzbDlC2nIUWG+UGmh
	ySv6MHYugdnWjDZeBK3peFQpQ3Za6Q52z0kDkPxdX7U2o+rcPsUJJlNseMQwjCEGzJ7E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ...
Message-Id: <E1kpDJq-0005eI-FO@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:36:58 +0000

commit 5ab684cb3e4d078f246e6fa2d8bc445959b6820e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:30 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:26 2020 +0000

    libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ...
    
    which support naming and use 'libxl_pci_bdf' rather than 'libxl_device_pci',
    as replacements for libxl_device_pci_assignable_add/remove/list/list_free().
    
    libxl_pci_bdf_assignable_add() takes a 'name' parameter which is stored in
    xenstore and facilitates two addtional functions added by this patch:
    libxl_pci_bdf_assignable_name2bdf() and libxl_pci_bdf_assignable_bdf2name().
    Currently there are no callers of these two functions. They will be added in
    a subsequent patch.
    
    libxl_device_pci_assignable_add/remove/list/list_free() are left in place
    for compatibility but are re-implemented in terms of the newly introduced
    functions.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h        |  36 ++++++++--
 tools/libs/light/libxl_pci.c | 166 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 171 insertions(+), 31 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 1fa4c5806d..fda611f889 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -469,6 +469,13 @@
  */
 #define LIBXL_HAVE_PCI_BDF 1
 
+/*
+ * LIBXL_HAVE_PCI_ASSIGNABLE_BDF indicates that the
+ * libxl_pci_bdf_assignable_add/remove/list/list_free() functions all
+ * exist.
+ */
+#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2357,9 +2364,9 @@ int libxl_device_events_handler(libxl_ctx *ctx,
                                 LIBXL_EXTERNAL_CALLERS_ONLY;
 
 /*
- * Functions related to making devices assignable -- that is, bound to
- * the pciback driver, ready to be given to a guest via
- * libxl_pci_device_add.
+ * Functions related to making PCI devices with the specified BDF
+ * assignable -- that is, bound to the pciback driver, ready to be given to
+ * a guest via libxl_pci_device_add.
  *
  * - ..._add() will unbind the device from its current driver (if
  * already bound) and re-bind it to pciback; at that point it will be
@@ -2371,16 +2378,31 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * rebind is non-zero, attempt to assign it back to the driver
  * from whence it came.
  *
- * - ..._list() will return a list of the PCI devices available to be
+ * - ..._list() will return a list of the PCI BDFs available to be
  * assigned.
  *
  * add and remove are idempotent: if the device in question is already
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
+int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                 const char *name, int rebind);
+int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                    int rebind);
+libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num);
+void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num);
+libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
+                                                 const char *name);
+char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
+                                        libxl_pci_bdf *pcibdf);
+
+/* Compatibility functions - Use libxl_pci_bdf_assignable_* instead */
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind);
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
+                                                   int *num);
 void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 448fe96951..e11574e73f 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -426,10 +426,10 @@ static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
     xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
+libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcis = NULL, *new;
+    libxl_pci_bdf *pcibdfs = NULL, *new;
     struct dirent *de;
     DIR *dir;
 
@@ -450,17 +450,17 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcibdfs, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcis = new;
-        new = pcis + *num;
+        pcibdfs = new;
+        new = pcibdfs + *num;
 
-        libxl_device_pci_init(new);
-        pcibdf_struct_fill(&new->bdf, dom, bus, dev, func);
+        libxl_pci_bdf_init(new);
+        pcibdf_struct_fill(new, dom, bus, dev, func);
 
-        if (pci_info_xs_read(gc, &new->bdf, "domid")) /* already assigned */
+        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
             continue;
 
         (*num)++;
@@ -469,15 +469,15 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
     closedir(dir);
 out:
     GC_FREE;
-    return pcis;
+    return pcibdfs;
 }
 
-void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num)
 {
     int i;
 
     for (i = 0; i < num; i++)
-        libxl_device_pci_dispose(&list[i]);
+        libxl_pci_bdf_dispose(&list[i]);
 
     free(list);
 }
@@ -745,6 +745,7 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 
 static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
                                          libxl_pci_bdf *pcibdf,
+                                         const char *name,
                                          int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -753,6 +754,23 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     int rc;
     struct stat st;
 
+    /* Sanitise any name that was passed */
+    if (name) {
+        unsigned int i, n = strlen(name);
+
+        if (n > 64) { /* Reasonable upper bound on name length */
+            LOG(ERROR, "Name too long");
+            return ERROR_FAIL;
+        }
+
+        for (i = 0; i < n; i++) {
+            if (!isgraph(name[i])) {
+                LOG(ERROR, "Names may only include printable characters");
+                return ERROR_FAIL;
+            }
+        }
+    }
+
     /* Local copy for convenience */
     dom = pcibdf->domain;
     bus = pcibdf->bus;
@@ -773,7 +791,7 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     }
     if ( rc ) {
         LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func);
-        goto quarantine;
+        goto name;
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
@@ -804,7 +822,12 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
         return ERROR_FAIL;
     }
 
-quarantine:
+name:
+    if (name)
+        pci_info_xs_write(gc, pcibdf, "name", name);
+    else
+        pci_info_xs_remove(gc, pcibdf, "name");
+
     /*
      * DOMID_IO is just a sentinel domain, without any actual mappings,
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
@@ -868,34 +891,87 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
         }
     }
 
+    pci_info_xs_remove(gc, pcibdf, "name");
+
     return 0;
 }
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind)
+int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                 const char *name, int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, rebind);
+    rc = libxl__pci_bdf_assignable_add(gc, pcibdf, name, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind)
+int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                    int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_remove(gc, &pci->bdf, rebind);
+    rc = libxl__pci_bdf_assignable_remove(gc, pcibdf, rebind);
 
     GC_FREE;
     return rc;
 }
 
+libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
+                                                 const char *name)
+{
+    GC_INIT(ctx);
+    char **bdfs;
+    libxl_pci_bdf *pcibdf = NULL;
+    unsigned int i, n;
+
+    bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n);
+    if (!n)
+        goto out;
+
+    pcibdf = calloc(1, sizeof(*pcibdf));
+    if (!pcibdf)
+        goto out;
+
+    for (i = 0; i < n; i++) {
+        unsigned dom, bus, dev, func;
+        const char *tmp;
+
+        if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4)
+            continue;
+
+        pcibdf_struct_fill(pcibdf, dom, bus, dev, func);
+
+        tmp = pci_info_xs_read(gc, pcibdf, "name");
+        if (tmp && !strcmp(tmp, name))
+            goto out;
+    }
+
+    free(pcibdf);
+    pcibdf = NULL;
+
+out:
+    GC_FREE;
+    return pcibdf;
+}
+
+char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
+                                        libxl_pci_bdf *pcibdf)
+{
+    GC_INIT(ctx);
+    char *name = NULL, *tmp = pci_info_xs_read(gc, pcibdf, "name");
+
+    if (tmp)
+        name = strdup(tmp);
+
+    GC_FREE;
+    return name;
+}
+
 /*
  * This function checks that all functions of a device are bound to pciback
  * driver. It also initialises a bit-mask of which function numbers are present
@@ -1490,17 +1566,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
 
 static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
 {
-    libxl_device_pci *pcis;
+    libxl_pci_bdf *pcibdfs;
     int num, i;
 
-    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
 
     for (i = 0; i < num; i++) {
-        if (COMPARE_BDF(pcibdf, &pcis[i].bdf))
+        if (COMPARE_BDF(pcibdf, &pcibdfs[i]))
             break;
     }
 
-    libxl_device_pci_assignable_list_free(pcis, num);
+    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
 
     return i < num;
 }
@@ -1551,7 +1627,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     if (rc) goto out;
 
     if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
-        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, 1);
+        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, NULL, 1);
         if ( rc )
             goto out;
     }
@@ -2449,6 +2525,48 @@ DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind)
+{
+    return libxl_pci_bdf_assignable_add(ctx, &pci->bdf, NULL, rebind);
+}
+
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind)
+{
+    return libxl_pci_bdf_assignable_remove(ctx, &pci->bdf, rebind);
+}
+
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
+                                                   int *num)
+{
+    libxl_pci_bdf *pcibdfs = libxl_pci_bdf_assignable_list(ctx, num);
+    libxl_device_pci *pcis;
+    unsigned int i;
+
+    if (!pcibdfs)
+        return NULL;
+
+    pcis = calloc(*num, sizeof(*pcis));
+    if (!pcis) {
+        libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
+        return NULL;
+    }
+
+    for (i = 0; i < *num; i++) {
+        libxl_device_pci_init(&pcis[i]);
+        libxl_pci_bdf_copy(ctx, &pcis[i].bdf, &pcibdfs[i]);
+    }
+
+    libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
+    return pcis;
+}
+
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+{
+    libxl_device_pci_list_free(list, num);
+}
+
 /*
  * Local variables:
  * mode: C
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:37:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:37:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54588.95078 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDK2-00084B-Dk; Tue, 15 Dec 2020 16:37:10 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54588.95078; Tue, 15 Dec 2020 16:37:10 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDK2-000840-7r; Tue, 15 Dec 2020 16:37:10 +0000
Received: by outflank-mailman (input) for mailman id 54588;
 Tue, 15 Dec 2020 16:37:08 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDK0-00081x-Jh
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:08 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDK0-0002wt-J3
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:08 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDK0-0005fC-IH
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:08 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=S7PlQqRXFVb/zxzGdDHW4f1AEDv6GIK4PTBm1rd80/I=; b=RV2m1vBm9xVk3rJ1+1DdDIZHM6
	++gb9iGupyzbQa04/utF5mU1+k0TFum2qdwI2j9XfYIXwwkbbEY0PSu/KKNpOdovVeHlSJx6tMnHr
	UjeHJpBhndOjwB6xtf9Xyr3FO6yes/r5SbE4HbAyi/WONNFziIIoww46HiPZPuEBtNuY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xl: support naming of assignable devices
Message-Id: <E1kpDK0-0005fC-IH@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:37:08 +0000

commit 93c16ae47baf7e92477c34d434719bfed3ccad84
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:31 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:30 2020 +0000

    xl: support naming of assignable devices
    
    This patch converts libxl to use libxl_pci_bdf_assignable_add/remove/list/
    list_free() rather than libxl_device_pci_assignable_add/remove/list/
    list_free(), which then allows naming of assignable devices to be supported.
    
    With this patch applied 'xl pci-assignable-add' will take an optional '--name'
    parameter, 'xl pci-assignable-remove' can be passed either a BDF or a name and
    'xl pci-assignable-list' will take a optional '--show-names' flag which
    determines whether names are displayed in its output.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xl/xl_cmdtable.c |  12 ++++--
 tools/xl/xl_pci.c      | 100 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 74 insertions(+), 38 deletions(-)

diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 30e17a2848..bd8af12ff3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -105,21 +105,25 @@ struct cmd_spec cmd_table[] = {
     { "pci-assignable-add",
       &main_pciassignable_add, 0, 1,
       "Make a device assignable for pci-passthru",
-      "<BDF>",
+      "[options] <BDF>",
+      "-n NAME, --name=NAME    Name the assignable device.\n"
       "-h                      Print this help.\n"
     },
     { "pci-assignable-remove",
       &main_pciassignable_remove, 0, 1,
       "Remove a device from being assignable",
-      "[options] <BDF>",
+      "[options] <BDF>|NAME",
       "-h                      Print this help.\n"
       "-r                      Attempt to re-assign the device to the\n"
-      "                        original driver"
+      "                        original driver."
     },
     { "pci-assignable-list",
       &main_pciassignable_list, 0, 0,
       "List all the assignable pci devices",
-      "",
+      "[options]",
+      "-h                      Print this help.\n"
+      "-n, --show-names        Display assignable device names where\n"
+      "                        supplied.\n"
     },
     { "pause",
       &main_pause, 0, 1,
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 9c24496cb2..eb29b4e08d 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -152,55 +152,68 @@ int main_pciattach(int argc, char **argv)
     return EXIT_SUCCESS;
 }
 
-static void pciassignable_list(void)
+static void pciassignable_list(bool show_names)
 {
-    libxl_device_pci *pcis;
+    libxl_pci_bdf *pcibdfs;
     int num, i;
 
-    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
 
-    if ( pcis == NULL )
+    if ( pcibdfs == NULL )
         return;
     for (i = 0; i < num; i++) {
-        printf("%04x:%02x:%02x.%01x\n",
-               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
-               pcis[i].bdf.func);
+        libxl_pci_bdf *pcibdf = &pcibdfs[i];
+        char *name = show_names ?
+            libxl_pci_bdf_assignable_bdf2name(ctx, pcibdf) : NULL;
+
+        printf("%04x:%02x:%02x.%01x %s\n",
+               pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
+               name ?: "");
+
+        free(name);
     }
-    libxl_device_pci_assignable_list_free(pcis, num);
+    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
 {
     int opt;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
-        /* No options */
+    static struct option opts[] = {
+        {"show-names", 0, 0, 'n'},
+        COMMON_LONG_OPTS
+    };
+    bool show_names = false;
+
+    SWITCH_FOREACH_OPT(opt, "n", opts, "pci-assignable-list", 0) {
+    case 'n':
+        show_names = true;
+        break;
     }
 
-    pciassignable_list();
+    pciassignable_list(show_names);
     return 0;
 }
 
-static int pciassignable_add(const char *bdf, int rebind)
+static int pciassignable_add(const char *bdf, const char *name, int rebind)
 {
-    libxl_device_pci pci;
+    libxl_pci_bdf pcibdf;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pci);
+    libxl_pci_bdf_init(&pcibdf);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pcibdf, bdf)) {
         fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
+    if (libxl_pci_bdf_assignable_add(ctx, &pcibdf, name, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pci);
+    libxl_pci_bdf_dispose(&pcibdf);
     xlu_cfg_destroy(config);
 
     return r;
@@ -210,39 +223,58 @@ int main_pciassignable_add(int argc, char **argv)
 {
     int opt;
     const char *bdf = NULL;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
-        /* No options */
+    static struct option opts[] = {
+        {"name", 1, 0, 'n'},
+        COMMON_LONG_OPTS
+    };
+    const char *name = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "n:", opts, "pci-assignable-add", 0) {
+    case 'n':
+        name = optarg;
+        break;
     }
 
     bdf = argv[optind];
 
-    if (pciassignable_add(bdf, 1))
+    if (pciassignable_add(bdf, name, 1))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciassignable_remove(const char *bdf, int rebind)
+static int pciassignable_remove(const char *ident, int rebind)
 {
-    libxl_device_pci pci;
+    libxl_pci_bdf *pcibdf;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pci);
-
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
-        fprintf(stderr, "pci-assignable-remove: malformed BDF \"%s\"\n", bdf);
-        exit(2);
+    pcibdf = libxl_pci_bdf_assignable_name2bdf(ctx, ident);
+    if (!pcibdf) {
+        pcibdf = calloc(1, sizeof(*pcibdf));
+
+        if (!pcibdf) {
+            fprintf(stderr,
+                    "pci-assignable-remove: failed to allocate memory\n");
+            exit(2);
+        }
+
+        libxl_pci_bdf_init(pcibdf);
+        if (xlu_pci_parse_bdf(config, pcibdf, ident)) {
+            fprintf(stderr,
+                    "pci-assignable-remove: malformed BDF '%s'\n", ident);
+            exit(2);
+        }
     }
 
-    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
+    if (libxl_pci_bdf_assignable_remove(ctx, pcibdf, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pci);
+    libxl_pci_bdf_dispose(pcibdf);
+    free(pcibdf);
     xlu_cfg_destroy(config);
 
     return r;
@@ -251,7 +283,7 @@ static int pciassignable_remove(const char *bdf, int rebind)
 int main_pciassignable_remove(int argc, char **argv)
 {
     int opt;
-    const char *bdf = NULL;
+    const char *ident = NULL;
     int rebind = 0;
 
     SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
@@ -260,9 +292,9 @@ int main_pciassignable_remove(int argc, char **argv)
         break;
     }
 
-    bdf = argv[optind];
+    ident = argv[optind];
 
-    if (pciassignable_remove(bdf, rebind))
+    if (pciassignable_remove(ident, rebind))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:37:20 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:37:20 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54594.95080 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDKC-0008Ch-Cx; Tue, 15 Dec 2020 16:37:20 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54594.95080; Tue, 15 Dec 2020 16:37:20 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDKC-0008CY-9S; Tue, 15 Dec 2020 16:37:20 +0000
Received: by outflank-mailman (input) for mailman id 54594;
 Tue, 15 Dec 2020 16:37:18 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKA-0008BE-Mz
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:18 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKA-0002ww-Ls
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:18 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKA-0005gJ-L7
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:18 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HEnJY7ZKJnfIHoTUDpS5LR3kf6ut/LSnWyVIUZ7Cxwk=; b=tsSrVTtvUFYk2WpoatY06bGQ+X
	IAzWMkU8nUxoGhggJ+IkBw9nDswMqEr2Ktda8oMpGHElRaq43PO1ZkaJulnU3++Ou0LyhmOsln5/t
	zNkjNos456YjLM43oh04Dbqs2lpkIQBXBL/+7NvSQTXjUJsFhvU11cXGCH8inJ8mDz8Q=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING
Message-Id: <E1kpDKA-0005gJ-L7@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:37:18 +0000

commit e1141654c3745588f9f13e8cf7de19cdb987ae5d
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:32 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:34 2020 +0000

    docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING
    
    Since assignable devices can be named, a subsequent patch will support use
    of a PCI_SPEC_STRING containing a 'name' parameter instead of a 'bdf'. In
    this case the name will be used to look up the 'bdf' in the list of assignable
    (or assigned) devices.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index 4dd73bc498..db3360307c 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -51,7 +51,7 @@ is not specified, or if it is specified with an empty value (whether
 positionally or explicitly).
 
 B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
-B<bdf> will be ignored.
+B<bdf> or B<name> will be ignored.
 
 =head1 Positional Parameters
 
@@ -70,7 +70,11 @@ B<*> to indicate all functions of a multi-function device.
 
 =item Default Value
 
-None. This parameter is mandatory as it identifies the device.
+None. This parameter is mandatory in its positional form. As a non-positional
+parameter it is also mandatory unless a B<name> parameter is present, in
+which case B<bdf> must not be present since the B<name> will be used to find
+the B<bdf> in the list of assignable devices. See L<xl(1)> for more information
+on naming assignable devices.
 
 =back
 
@@ -194,4 +198,21 @@ B<NOTE>: This overrides the global B<rdm> option.
 
 =back
 
+=item B<name>=I<STRING>
+
+=over 4
+
+=item Description
+
+This is the name given when the B<BDF> was made assignable. See L<xl(1)> for
+more information on naming assignable devices.
+
+=item Default Value
+
+None. This parameter must not be present if a B<bdf> parameter is present.
+If a B<bdf> parameter is not present then B<name> is mandatory as it is
+required to look up the B<BDF> in the list of assignable devices.
+
+=back
+
 =back
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:37:30 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:37:30 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54596.95084 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDKM-0008J8-F3; Tue, 15 Dec 2020 16:37:30 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54596.95084; Tue, 15 Dec 2020 16:37:30 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDKM-0008Iz-B4; Tue, 15 Dec 2020 16:37:30 +0000
Received: by outflank-mailman (input) for mailman id 54596;
 Tue, 15 Dec 2020 16:37:28 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKK-0008I8-Pb
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:28 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKK-0002x1-Ow
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:28 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDKK-0005gv-OA
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:37:28 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6ULmaU1uKQue7/hvns4RIY84kRoreLnw4ZAv0rix3n8=; b=Almh8+ljxzUutXYfiCF0Io9lSj
	J0D1tK2lrVXCvZ3WGaLt2/L30eaPPFLPMPasE8yLodc89Yx5fIt9jRsMGG01+8qdpouObmTuvvGRp
	w3FyejnBqAMhJgwTH4VklAn/Kx1G9VA6RdjqvuiFuHILJYn1bUlDbJxnZoruW2I2drds=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] libxl / libxlu: support 'xl pci-attach/detach' by name
Message-Id: <E1kpDKK-0005gv-OA@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:37:28 +0000

commit 8bf0fab14256057bbd145563151814300476bb28
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:33 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:34 2020 +0000

    libxl / libxlu: support 'xl pci-attach/detach' by name
    
    This patch adds a 'name' field into the idl for 'libxl_device_pci' and
    libxlu_pci_parse_spec_string() is modified to parse the new 'name'
    parameter of PCI_SPEC_STRING detailed in the updated documention in
    xl-pci-configuration(5).
    
    If the 'name' field is non-NULL then both libxl_device_pci_add() and
    libxl_device_pci_remove() will use it to look up the device BDF in
    the list of assignable devices.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h            |  6 ++++
 tools/libs/light/libxl_pci.c     | 67 +++++++++++++++++++++++++++++++++++++---
 tools/libs/light/libxl_types.idl |  1 +
 tools/libs/util/libxlu_pci.c     |  7 ++++-
 4 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index fda611f889..90a7aa9b73 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -476,6 +476,12 @@
  */
 #define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of
+ * libxl_device_pci is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_NAME 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index e11574e73f..5d83db2a59 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -60,6 +60,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             int num,
                                             const libxl_device_pci *pci)
 {
+    if (pci->name) {
+        flexarray_append(back, GCSPRINTF("name-%d", num));
+        flexarray_append(back, GCSPRINTF("%s", pci->name));
+    }
     flexarray_append(back, GCSPRINTF("key-%d", num));
     flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
@@ -284,6 +288,7 @@ retry_transaction:
 
 retry_transaction2:
     t = xs_transaction_start(ctx->xsh);
+    xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i));
@@ -322,6 +327,12 @@ retry_transaction2:
             xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
+        tmppath = GCSPRINTF("%s/name-%d", be_path, j);
+        tmp = libxl__xs_read(gc, t, tmppath);
+        if (tmp) {
+            xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp));
+            xs_rm(ctx->xsh, t, tmppath);
+        }
     }
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
@@ -1610,6 +1621,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
+    if (pci->name) {
+        libxl_pci_bdf *pcibdf =
+            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
+
+        if (!pcibdf) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
+             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+
+        libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf);
+        libxl_pci_bdf_dispose(pcibdf);
+        free(pcibdf);
+    }
+
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
         rc = xc_test_assign_device(ctx->xch, domid,
                                    pci_encode_bdf(&pci->bdf));
@@ -1758,11 +1786,19 @@ static void device_pci_add_done(libxl__egc *egc,
     libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
-        LOGD(ERROR, domid,
-             "libxl__device_pci_add  failed for "
-             "PCI device %x:%x:%x.%x (rc %d)",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
-             rc);
+        if (pci->name) {
+            LOGD(ERROR, domid,
+                 "libxl__device_pci_add failed for "
+                 "PCI device '%s' (rc %d)",
+                 pci->name,
+                 rc);
+        } else {
+            LOGD(ERROR, domid,
+                 "libxl__device_pci_add failed for "
+                 "PCI device %x:%x:%x.%x (rc %d)",
+                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                 rc);
+        }
         pci_info_xs_remove(gc, &pci->bdf, "domid");
     }
     libxl_device_pci_dispose(pci);
@@ -2279,6 +2315,23 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
+    if (pci->name) {
+        libxl_pci_bdf *pcibdf =
+            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
+
+        if (!pcibdf) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
+             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+
+        libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf);
+        libxl_pci_bdf_dispose(pcibdf);
+        free(pcibdf);
+    }
+
     prs->orig_vdev = pci->vdevfn & ~7U;
 
     if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
@@ -2413,6 +2466,10 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
 
+    s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr));
+    if (s)
+        pci->name = strdup(s);
+
     return 0;
 }
 
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 21a2cf5c1c..32cc99beff 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -779,6 +779,7 @@ libxl_pci_bdf = Struct("pci_bdf", [
 
 libxl_device_pci = Struct("device_pci", [
     ("bdf", libxl_pci_bdf),
+    ("name", string),
     ("vdevfn", uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index a8b6ce5427..543a1f80e9 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -151,6 +151,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
 {
     const char *ptr = str;
     bool bdf_present = false;
+    bool name_present = false;
     int ret;
 
     /* Attempt to parse 'bdf' as positional parameter */
@@ -193,6 +194,10 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
             pcidev->power_mgmt = atoi(val);
         } else if (!strcmp(key, "rdm_policy")) {
             ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
+        } else if (!strcmp(key, "name")) {
+            name_present = true;
+            pcidev->name = strdup(val);
+            if (!pcidev->name) ret = ERROR_NOMEM;
         } else {
             XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
             ret = ERROR_INVAL;
@@ -205,7 +210,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
             return ret;
     }
 
-    if (!bdf_present)
+    if (!(bdf_present ^ name_present))
         return ERROR_INVAL;
 
     return 0;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 15 16:55:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 15 Dec 2020 16:55:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.54708.95219 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDbM-0003PB-2J; Tue, 15 Dec 2020 16:55:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 54708.95219; Tue, 15 Dec 2020 16:55:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpDbL-0003P3-VP; Tue, 15 Dec 2020 16:55:03 +0000
Received: by outflank-mailman (input) for mailman id 54708;
 Tue, 15 Dec 2020 16:55:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDbK-0003Oy-9B
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:55:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDbK-0003K1-4p
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpDbK-0002Tb-2z
 for xen-changelog@lists.xenproject.org; Tue, 15 Dec 2020 16:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0Fgv51x9Seu+vTwOOnO3sjEA1xwM22dAnImmYDY1W+w=; b=DSA48g5jw+/i1dFjpB/2V7e+OC
	Om2X01UGSj/mgnQFwtPFbZRSx1eASAsMF/Ecx/6mtzoKG6gQI5D6gejF1FtogD67vlcCWcPDhqsw1
	26+ZWs1JhpPR8tobbaiuDibsqsJ7lL8Erowv5/NhBuHz843ELZPrDirOsN8sT+aNp50U=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [mini-os master] mini-os: netfront: Handle init failure when no vifs are provided
Message-Id: <E1kpDbK-0002Tb-2z@xenbits.xenproject.org>
Date: Tue, 15 Dec 2020 16:55:02 +0000

commit cc8b330e5729312a0632fd0e9f28e8f136a76182
Author:     Costin Lupu <costin.lupu@cs.pub.ro>
AuthorDate: Tue Dec 15 16:50:12 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:52:00 2020 +0000

    mini-os: netfront: Handle init failure when no vifs are provided
    
    These changes deal with the case when no vifs are created. This can happen when
    no vif is provided in the config file for mini-os images with netfront support.
    
    Signed-off-by: Costin Lupu <costin.lupu@cs.pub.ro>
    Reviewed-by: Samuel Thibault <samuel.thibault@@ens-lyon.org>
---
 lwip-net.c | 4 ++++
 netfront.c | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lwip-net.c b/lwip-net.c
index 7e0d871..16950d3 100644
--- a/lwip-net.c
+++ b/lwip-net.c
@@ -348,6 +348,10 @@ void start_networking(void)
   tprintk("Waiting for network.\n");
 
   dev = init_netfront(NULL, NULL, rawmac, &ip);
+  if (!dev) {
+      tprintk("Error initializing netfront.\n");
+      return;
+  }
   netmask_str = netfront_get_netmask(dev);
   gw_str = netfront_get_gateway(dev);
   
diff --git a/netfront.c b/netfront.c
index 2075410..f927e99 100644
--- a/netfront.c
+++ b/netfront.c
@@ -383,6 +383,7 @@ char *netfront_get_gateway(struct netfront_dev *dev)
 
 static struct netfront_dev *_init_netfront(struct netfront_dev *dev)
 {
+    int domid;
     xenbus_transaction_t xbt;
     char* err = NULL;
     char* message=NULL;
@@ -393,6 +394,12 @@ static struct netfront_dev *_init_netfront(struct netfront_dev *dev)
     int i;
     char path[256];
 
+    snprintf(path, sizeof(path), "%s/backend-id", dev->nodename);
+    domid = xenbus_read_integer(path);
+    if (domid < 0)
+        return NULL;
+    dev->dom = domid;
+
     printk("net TX ring size %lu\n", (unsigned long) NET_TX_RING_SIZE);
     printk("net RX ring size %lu\n", (unsigned long) NET_RX_RING_SIZE);
     init_SEMAPHORE(&dev->tx_sem, NET_TX_RING_SIZE);
@@ -407,8 +414,6 @@ static struct netfront_dev *_init_netfront(struct netfront_dev *dev)
         BUG_ON(dev->rx_buffers[i].page == NULL);
     }
 
-    snprintf(path, sizeof(path), "%s/backend-id", dev->nodename);
-    dev->dom = xenbus_read_integer(path);
 #ifdef HAVE_LIBC
     if (dev->netif_rx == NETIF_SELECT_RX)
         evtchn_alloc_unbound(dev->dom, netfront_select_handler, dev, &dev->evtchn);
--
generated by git-patchbot for /home/xen/git/mini-os.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55020.95658 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrK-0001Vz-Ob; Wed, 16 Dec 2020 06:00:22 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55020.95658; Wed, 16 Dec 2020 06:00:22 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrK-0001Vq-Kj; Wed, 16 Dec 2020 06:00:22 +0000
Received: by outflank-mailman (input) for mailman id 55020;
 Wed, 16 Dec 2020 06:00:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrB-0001VW-3R
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrB-0007uF-1l
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrB-0000RT-0d
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=eZaf4UMMDxsPX7hLNUp+Ft+n2PteE3Fi/3NypBrvu/U=; b=DmU3hdIoAzbbqj3GqUIAlFa/Ix
	MADsnjX1jgmQAMclYM5qoafXNTRbASzQeizHJhxgQ6B6X7j9BNyBLfJQU6+ZeVIvrnZmjLA/19f71
	vwZkIaFExS6rWiT34ryjnO6XTc3fnrjBZyWGpG0/9S8cmOdXFO3roNRoFlKyyeb5xGaY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpPrB-0000RT-0d@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:13 +0000

commit 9c898a82b84247fb02deb8ae2adb1f749631a7b1
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:38 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 7bd959f28b..62a17a686e 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -419,7 +419,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -429,7 +430,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -457,14 +458,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -1001,7 +1003,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1041,7 +1043,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1117,7 +1119,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1256,7 +1258,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1516,7 +1518,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index c4c32bc88f..29d638fbc5 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55022.95665 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrM-0001Wr-QJ; Wed, 16 Dec 2020 06:00:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55022.95665; Wed, 16 Dec 2020 06:00:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrM-0001Wj-NL; Wed, 16 Dec 2020 06:00:24 +0000
Received: by outflank-mailman (input) for mailman id 55022;
 Wed, 16 Dec 2020 06:00:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrL-0001WZ-6P
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrL-0007uL-5A
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrL-0000SR-42
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aIq5E4cLhu7CnbvNVTwQyRQd7VCvljepiLVgfGiTM5M=; b=kQQ4C+G+eITTwCapMGYphMik2W
	4cHSMaGw7D6qs358lchdP41TlTx5Ip7rRVHchlu7nI4zy0KaZbWUiriRVt4MuRbQRGNVnaHFUAEzw
	K5cNu0/Sc/aQjPJYqI6zg5mOa62w9hVZKPh/thoL6NHHwavNBxX4NDeT7cVilZ1+XGbU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpPrL-0000SR-42@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:23 +0000

commit da67712173474c31695a56a269a8b069f7eb36a6
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:43 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 62a17a686e..2f989524b4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1270,13 +1270,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1298,7 +1302,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1313,7 +1317,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1322,12 +1333,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55021.95663 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrK-0001WK-S7; Wed, 16 Dec 2020 06:00:22 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55021.95663; Wed, 16 Dec 2020 06:00:22 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrK-0001W1-M4; Wed, 16 Dec 2020 06:00:22 +0000
Received: by outflank-mailman (input) for mailman id 55021;
 Wed, 16 Dec 2020 06:00:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPr1-0000xk-0c
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPr0-0007u8-UR
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPr0-0000Pm-Rq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zQfRhODWRiuGUAJg5gvOlepVV22kEv9b1c3EaSkY7Fw=; b=1EsA/i/GJbvj4lY5/NGyEvCaKY
	L4qtAv2jUlalOUXXrASfa5Qqrb0WAjmrSn5S5T+RO32qSHLvXmmBA6+TPijqdi9UvvCKMznBnQ47O
	kq5pk9yVS46jTJ08FcwsTvS7DgNgQcZtHSfuzhhD3GQzg9G1LzfCKxaB8TQktBWiwKQY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpPr0-0000Pm-Rq@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:02 +0000

commit f130d5f013b205d1b15fa8395e473e422cb51945
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:05:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:16 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55023.95670 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrW-0001Yz-SH; Wed, 16 Dec 2020 06:00:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55023.95670; Wed, 16 Dec 2020 06:00:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrW-0001Yr-Oy; Wed, 16 Dec 2020 06:00:34 +0000
Received: by outflank-mailman (input) for mailman id 55023;
 Wed, 16 Dec 2020 06:00:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrV-0001YZ-Aj
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrV-0007uR-9F
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrV-0000T7-7R
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1+fg5r6cZupHZj50wSh+OxeTB9EC+vKWHNzYWGFEYrY=; b=ZjPeG0l2UWYrftuy5y3QDvxM/v
	9hz5Tt9u+TJEvRGPH1GpAE3V5Lls8vBM+BfOnTZE09EUfN/t/l02NCCHCO8Z3c+1cBvOmqefAWsiz
	biu5xmZq1tXbj1kfNjXAvKy/GpkMFCUBKnUsvat8d/SG6sOYtqpFN/3QCRH4Kf+enIzk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpPrV-0000T7-7R@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:33 +0000

commit 3beffb3ed0e999e38a6ff4dec042b38c23d77e48
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:47 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2f989524b4..c971519e54 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -927,11 +927,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -964,7 +959,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -984,6 +978,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -1000,18 +997,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55024.95673 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrg-0001ax-U0; Wed, 16 Dec 2020 06:00:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55024.95673; Wed, 16 Dec 2020 06:00:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrg-0001ap-Qt; Wed, 16 Dec 2020 06:00:44 +0000
Received: by outflank-mailman (input) for mailman id 55024;
 Wed, 16 Dec 2020 06:00:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrf-0001ac-DU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrf-0007uu-Cn
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrf-0000Tw-BI
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Vz+FnX5bPfLTCm9j2YHvkIvxbnY64hvJD3STTgG1z+4=; b=vW+i/mIL0XzuZ5XnGoJBOb6iIr
	G+megBvI4rUE2ct/4fmtspwNPcnXMEMvgZiHLf6sEYwcvyOJW2WPHnRrzsSIVtw4uGv2zVLEn+4/8
	HUJq3XGnXOB/IKNDZ81aKkfBbBNWq0TyUPZQfLOFoZjkrhrcoUchSUfDTPrgpvy1ybqo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpPrf-0000Tw-BI@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:43 +0000

commit 4e298fa40781231ddc3f17e3e14e869c1c591722
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:53 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:00:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:00:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55025.95677 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrr-0001dL-0Y; Wed, 16 Dec 2020 06:00:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55025.95677; Wed, 16 Dec 2020 06:00:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPrq-0001dF-Tv; Wed, 16 Dec 2020 06:00:54 +0000
Received: by outflank-mailman (input) for mailman id 55025;
 Wed, 16 Dec 2020 06:00:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrp-0001cz-GT
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrp-0007v1-Fo
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrp-0000UW-Et
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:00:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=p0QItifCkT8PJBpw5/DUHN/IvnCs4bigdBZUeI5XOqs=; b=l8+gO9OpH1WRxc5HV9WQ4uYR52
	7OC39N0RLeFTp6hPj9Z2PYHGnC++FFdXHeJKkeL8jeqjqvqelF7VjDdpwCaYkdKB2j6pSDuqSOc3J
	kh5qlYgT/AfTdqnsYHESrVOhzCx+nvt501CjzzSN9Xr6/+4ZJKV+8d9qCKm9WUPIIUno=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpPrp-0000UW-Et@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:00:53 +0000

commit 91992c72ed55185de07f44aacee499954143c9f3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:05:58 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c971519e54..f38196ae28 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1285,8 +1285,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1296,8 +1298,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1306,9 +1310,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1336,6 +1342,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 06359503f0..2d0d87ee89 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -372,7 +372,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -438,7 +438,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -473,9 +473,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55027.95682 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPs1-0001es-2S; Wed, 16 Dec 2020 06:01:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55027.95682; Wed, 16 Dec 2020 06:01:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPs0-0001ek-VQ; Wed, 16 Dec 2020 06:01:04 +0000
Received: by outflank-mailman (input) for mailman id 55027;
 Wed, 16 Dec 2020 06:01:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrz-0001ea-Jm
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrz-0007ws-Iv
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPrz-0000VN-Hx
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Hhv+atN2f+dZqt+k9kL0xElV+ptM68OoWE+Ul3QFPjg=; b=oN2QaEnn8ByPDEecrN7CRM0QUr
	dbymUCTrJ3AqSaFJB3A6/Ui2ZSBEABFeF9MWcbuDCTp9gfaEhkPIkLCnlvNDADpQG+UPsgQpjpl3n
	/WS2eEePfYaqRkKY8wX57YVyoO30dfUQS0qFvE7Ar2rElM1qRQHFU2f0J+UeYEmio7oc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: rework node removal
Message-Id: <E1kpPrz-0000VN-Hx@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:03 +0000

commit 117521e9c099d92f60753ff2bb30d97eef6e8137
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:03 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f38196ae28..dfdb64f3ee 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1089,74 +1089,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1167,11 +1169,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1209,7 +1213,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55028.95686 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsB-0001g7-3w; Wed, 16 Dec 2020 06:01:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55028.95686; Wed, 16 Dec 2020 06:01:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsB-0001fz-0s; Wed, 16 Dec 2020 06:01:15 +0000
Received: by outflank-mailman (input) for mailman id 55028;
 Wed, 16 Dec 2020 06:01:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPs9-0001fu-Np
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPs9-0007wz-Mg
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPs9-0000W4-L6
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jO0plL+PM3+zYCaF/gYgf/BR0bzBEFbuYZx7CVnsEN0=; b=TRgjbFo1tH+EqtqR8qOjBSd5iJ
	bay+j8SStKxZHj9QWkKPmqIUmwTs4pBiLKn1DGM60l1TI38ldriCi+kURyPSjYkMpokodrTj8NDu5
	2b3ojzCbnSUgqTXbOi2RK5hsF76mBNk6kXs2XIMUcpv5FKFnOsnCg1iydY5jj9fVfpDM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpPs9-0000W4-L6@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:13 +0000

commit 3d0e1a15b31b690018e57547c6b82f442b1cbc76
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:07 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index dfdb64f3ee..20a7a35815 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1120,8 +1120,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1133,7 +1133,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1145,6 +1145,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1174,8 +1175,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55029.95692 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsL-0001hf-6E; Wed, 16 Dec 2020 06:01:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55029.95692; Wed, 16 Dec 2020 06:01:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsL-0001hW-2P; Wed, 16 Dec 2020 06:01:25 +0000
Received: by outflank-mailman (input) for mailman id 55029;
 Wed, 16 Dec 2020 06:01:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsJ-0001hN-RX
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsJ-0007x7-Qg
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsJ-0000Wj-Oq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oSvEtG2++zpdvGLx12VwYr7N9DG+VundIMNHn01upVo=; b=fHukXYgkR+ZdvTJjQUedCOjqg6
	9B/yZn5UmfhHbZg5OOmYHZGB36SMacmf0G3HMHSO8yquG2FUDWHQk8Ian8vFwY1k1aeAWLMW4CKJ4
	UdB3Rc8Rgvo2bKnOKFCX+b5rLMiWXeH6m+XbcTve5pVD7gWOyJkDaYNGRMMGkK3NpZhE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpPsJ-0000Wj-Oq@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:23 +0000

commit 52593586d58086fe27cfbed3dc9beeae3d9c8c09
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:12 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 20a7a35815..79d305fbbe 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -403,14 +403,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -427,7 +427,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -439,12 +439,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -470,8 +471,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -480,16 +480,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -536,7 +536,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -582,8 +582,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -759,16 +758,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -947,13 +945,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1230,7 +1228,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1241,13 +1239,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1258,21 +1255,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1547,8 +1544,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 29d638fbc5..47ba0916db 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 2d0d87ee89..aa9942fcc2 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -650,12 +650,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -676,12 +676,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55030.95694 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsV-0001j4-8U; Wed, 16 Dec 2020 06:01:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55030.95694; Wed, 16 Dec 2020 06:01:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsV-0001iw-5X; Wed, 16 Dec 2020 06:01:35 +0000
Received: by outflank-mailman (input) for mailman id 55030;
 Wed, 16 Dec 2020 06:01:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsT-0001im-UZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsT-0007xF-Tr
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsT-0000XJ-T0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BaWIFLW0Jlw+ACSCAvwY5JZgEmvT5jfuXBHJanLk9WM=; b=n0tW7+PT5tjeAa910vqof6cENh
	9fpx3Er8RFqANYyYjuS1ER3D7+CoIwitr8mZXoCuzvo8TSJJDsFTD/VZ41C/P4/X7k2di/xXzE33v
	xqb+x8wOumk4o2OJKj50qwzigOoCNY9PpUGyDJZuMBLHoCjwVAjqTuji/VlsDNivvuG0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpPsT-0000XJ-T0@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:33 +0000

commit 5073c6b169dd12ec02afc145d4177f97831646e0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:17 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index cb8009cb68..2081f20f55 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See https://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 79d305fbbe..15ffbeb30f 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -470,8 +470,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1247,22 +1247,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 47ba0916db..53f1050859 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index aa9942fcc2..a0d1a11c83 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -582,6 +585,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -603,6 +659,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55031.95700 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsf-0001kg-Ao; Wed, 16 Dec 2020 06:01:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55031.95700; Wed, 16 Dec 2020 06:01:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsf-0001kZ-74; Wed, 16 Dec 2020 06:01:45 +0000
Received: by outflank-mailman (input) for mailman id 55031;
 Wed, 16 Dec 2020 06:01:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPse-0001kR-1a
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPse-0007xf-0m
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsd-0000Xt-W2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=IUvqmKrGFCKhJhqFeH4IkC+F+AUGWNA3Hm6E6oPXy2c=; b=5YGC1X9x/b/9DRg4ZgbFlW4q+M
	3qE3Xxj76sX1DgsAJ79pUC5Hy4TZ/7aMLg+FTxsT+wZQLqNjDwdeP0fkYRdUwEjkefPlAmL2WoO4g
	aPYLvFQwn1QHFtJbHtvNjCuq+1wLfrAapZt3+lVENgMBleDGM/ZcmlDSHuCU4+PTp+vM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpPsd-0000Xt-W2@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:43 +0000

commit 0a79a1b1d8fc6214f162b2d7b00f5d3533109820
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:21 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 15ffbeb30f..92bfd54cff 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -360,8 +360,8 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *p_ro_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -496,7 +496,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -568,10 +568,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1058,7 +1058,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1080,7 +1080,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1143,7 +1143,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1167,13 +1167,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1239,7 +1240,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1275,6 +1276,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1282,7 +1284,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53f1050859..eb19b71f5f 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index a0d1a11c83..9fad470f83 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -202,7 +202,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -240,7 +240,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -404,7 +404,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:01:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:01:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55032.95701 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsp-0001o7-CC; Wed, 16 Dec 2020 06:01:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55032.95701; Wed, 16 Dec 2020 06:01:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsp-0001nv-8d; Wed, 16 Dec 2020 06:01:55 +0000
Received: by outflank-mailman (input) for mailman id 55032;
 Wed, 16 Dec 2020 06:01:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPso-0001mV-4A
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPso-0007xn-3T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPso-0000Yd-2m
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:01:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sNE811xJ56vZjbl1d9WXCe43C8vVxRZCZBEdqjzavno=; b=hQLlSg5JD7sair4zMD7DjHhx9v
	f09mtbMFF8T70aajhyOb7BNSIoiP2eu/h7OyzGrJrLOv8BIU6WI/2Ohja/WCI3OUCAxams4HS+dp3
	P4x7S07KyL5hkmBkhI6zMCSgZMhtfxcyqk3aFUYo4skk6NrqR3kO0cj+8I/h7ZZGg/c8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpPso-0000Yd-2m@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:01:54 +0000

commit 228e5621ebdd3abd520fcdc712347f877880ee71
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:38 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:38 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55033.95705 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsz-0001ph-D3; Wed, 16 Dec 2020 06:02:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55033.95705; Wed, 16 Dec 2020 06:02:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPsz-0001pa-A8; Wed, 16 Dec 2020 06:02:05 +0000
Received: by outflank-mailman (input) for mailman id 55033;
 Wed, 16 Dec 2020 06:02:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsy-0001pO-7v
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsy-0007y6-6S
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPsy-0000ZT-5U
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cCoqb1oNCOeeMq2uDiXZfHi9zSIr2llvhKEziGLu/UA=; b=aCUYzUKHXW5aOPW+WyVOMwPfUa
	m2ilCv82rYStzuWt4HqZD32MBVMbZQAmuvyLkhsSkpHg0ZM55QfBiOFgaIQomDzaAvql/Ko7iJqiB
	oc3cSqwSkUeAjhnEODiRrULzJlHCVJCjdTROLWWR5rIrXt7FL/EEn/v181n1lmBHDLAo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpPsy-0000ZT-5U@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:04 +0000

commit f4405b67aa7f33d07dd374226b0b4e3bb1fefb69
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:43 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55034.95710 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPt9-0001rM-GD; Wed, 16 Dec 2020 06:02:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55034.95710; Wed, 16 Dec 2020 06:02:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPt9-0001rE-DQ; Wed, 16 Dec 2020 06:02:15 +0000
Received: by outflank-mailman (input) for mailman id 55034;
 Wed, 16 Dec 2020 06:02:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPt8-0001r6-A1
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPt8-0007yE-9L
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPt8-0000a4-8T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sFrFjX4MtzCkjCkW1Imfd/2JFSiBUgUlMy2L0PsqIzw=; b=d4jXIN+s451HW7r8yRpfmdrfkw
	tQZmgRop0aVlWi9E3Mtl+JBgUubO5wFFiAYCmvTF3N/EV7P0U/m08ASYOde2iA6oOnf9I5cn8lnED
	Q8BBVwapBRMN0i2IxKLmcv/tvCpAUcKdkrmvTWyXOSJ22a7c1e9jHfPT9s/gQkTLs3ZE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpPt8-0000a4-8T@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:14 +0000

commit 6fa3e05ff5a8083a0be29ac66d4d94bb57e252f2
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:48 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55035.95714 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtK-0001sc-I4; Wed, 16 Dec 2020 06:02:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55035.95714; Wed, 16 Dec 2020 06:02:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtK-0001sU-F2; Wed, 16 Dec 2020 06:02:26 +0000
Received: by outflank-mailman (input) for mailman id 55035;
 Wed, 16 Dec 2020 06:02:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtI-0001sI-Cy
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtI-0007yH-CG
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtI-0000ah-BT
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bcwvFlmSjnVJ6/+Q3EwpxjcTv0DvIc+wva5PmmLZY/U=; b=efJmT3JJI6k7L7gBZ1SytHByiG
	kW5omBXY+mvKBB5a7wMz9JkfthZOd6iwZy8sYp2Ya/1j0OQR2T9FHe/Ys/3ZmEfxI945Xzrj2uHe+
	dbxIiS8ahrqYzlnN0mrD+P5xV0WqrxDY+XtUIoEOA+pawKOsKYtmyX0bhacXV3vpNlMo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpPtI-0000ah-BT@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:24 +0000

commit 335ef5b2b49100444aaaff19032235b1283ef1ea
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:53 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:53 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55036.95718 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtU-0001uB-Jy; Wed, 16 Dec 2020 06:02:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55036.95718; Wed, 16 Dec 2020 06:02:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtU-0001u4-Gv; Wed, 16 Dec 2020 06:02:36 +0000
Received: by outflank-mailman (input) for mailman id 55036;
 Wed, 16 Dec 2020 06:02:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtS-0001te-Gs
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtS-0007yK-GD
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtS-0000bI-EW
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=50ZPqJGW1AbELfgDHKMtT1eVHhjxOHDg5XjvPQSOBT0=; b=ktbSkTsnAUHaBsHGsMbOmePFFF
	0wC7bPK7t0W2BuJg79iIdN0V+oFSTdijExQtadrmqnYIT8QIgZx2ImTvrbPBKazzn/n1WhzOONqH6
	uXf0pw/IginnTiDbdvGWqxObthQJOXBqRVYyh7/SmlGZ2PhA/LWLGhc2U8MAuJZ3hz/E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpPtS-0000bI-EW@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:34 +0000

commit 9e53440c3675f143130b72b7bf6ea17240e3c053
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:06:58 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:06:58 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55037.95722 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtd-0001vP-LW; Wed, 16 Dec 2020 06:02:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55037.95722; Wed, 16 Dec 2020 06:02:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtd-0001vG-IW; Wed, 16 Dec 2020 06:02:45 +0000
Received: by outflank-mailman (input) for mailman id 55037;
 Wed, 16 Dec 2020 06:02:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtc-0001v9-KI
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtc-0007ye-Jb
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtc-0000bx-IU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GvW/HLcTEgeLYs/CGXXu/wrA53B8uI6JH9JGwOZSq7E=; b=UHvAxkYxrSsa2rx2U73rr17vp4
	dVDEyyLjx5WtxyNbrldt8kn9L9DKWNquL+BWgKF1cZLsp1N63swDVgMINgxfxmBXXW4dSqYUkzcez
	DLKmMqcnvxO9vbxpoDru+ws/HY5Ho0HqS3hlbImhyqtOYdF9XYclsVjjeUD9RkxU1qIE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpPtc-0000bx-IU@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:44 +0000

commit 61d386343a576de37a8192c7621a4db01124a458
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:07:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:07:03 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:02:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:02:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55038.95725 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtn-0001wt-OZ; Wed, 16 Dec 2020 06:02:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55038.95725; Wed, 16 Dec 2020 06:02:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtn-0001wl-LX; Wed, 16 Dec 2020 06:02:55 +0000
Received: by outflank-mailman (input) for mailman id 55038;
 Wed, 16 Dec 2020 06:02:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtm-0001wd-NU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtm-0007yh-Mk
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtm-0000cX-Ly
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:02:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=N2+FRvqmXL7F5NKqS4YzedDoF/sjeWp+sRufH25zmxw=; b=r7b0poTBz6bGzm2DEKtxNU5oOD
	NCSMlLo92gEiv+aLUvEy/1/le3UTfWYPaLtdsfPpQsE3WfLXXxrEnWLngyken9BrIYJqnmjSvRxsF
	WoAQANhisBeozmE+A/1I5myxYxqboXBZVhb//kHVoYC/RNVKuW22lrqL2jjGgysG3BIA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpPtm-0000cX-Ly@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:02:54 +0000

commit b1c5e402c488e4d2b78de1d08b9e98feed136ee7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:07:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:07:52 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 92bfd54cff..505560a5de 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -104,6 +104,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -409,8 +410,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -426,6 +432,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -485,8 +494,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1248,8 +1258,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1904,6 +1918,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1924,6 +1939,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1946,7 +1962,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -1988,6 +2004,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 9fad470f83..dc635e9be3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -67,8 +67,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -188,6 +194,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -209,21 +218,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -289,58 +311,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -386,15 +434,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -503,8 +557,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -647,8 +701,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -729,6 +785,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55039.95732 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtx-0001y9-Qq; Wed, 16 Dec 2020 06:03:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55039.95732; Wed, 16 Dec 2020 06:03:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPtx-0001xz-NC; Wed, 16 Dec 2020 06:03:05 +0000
Received: by outflank-mailman (input) for mailman id 55039;
 Wed, 16 Dec 2020 06:03:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtw-0001xs-QW
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtw-0007z3-Pr
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPtw-0000dH-Ou
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kyP8+aXd8gw2R/NNxtcIRJfN3K7fXf6IB/QkJaKvrjI=; b=GbDBIzH3t+TV2hkE9oLwWu9hiL
	7XBKIiJ5X4xeZ8ujTJMQiFi6pMzykIaKNLj+2qxU38Km8bInr6FzVWcd9nuRSkrN0N89MpeaCp6mB
	Bfo9aoAK8uGM/E03FAohrltybzC8GXSLA8aJgb12EVxNn81ICW3fpJuO860ApWuJZOZ4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpPtw-0000dH-Ou@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:04 +0000

commit dc871dda66a1ac1e0fc1ca5e35e380a145aaa739
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:08:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:03 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..a194cbc76f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55040.95734 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPu7-0001zW-Rh; Wed, 16 Dec 2020 06:03:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55040.95734; Wed, 16 Dec 2020 06:03:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPu7-0001zO-Oi; Wed, 16 Dec 2020 06:03:15 +0000
Received: by outflank-mailman (input) for mailman id 55040;
 Wed, 16 Dec 2020 06:03:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPu6-0001zI-Ua
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPu6-0007zB-Tg
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPu6-0000dv-S2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jf9PNKZUR67gQPZYd0I8LBqzai7N/5q624p7ImvK3tU=; b=HhXf/wX/o7N1EfBqZSqTNagsA+
	Ll0HZ8p5sYJ+M8XTnTiBBoafuck6QHDxSzPkIVxKy/MPCbbuoDbCMYrIAErRU/6/41yOK7fpVdlXq
	H2bqPNCYsHzWRIwptk0aeYJZvuxW2elDUHeVxEBhveh3BzX2Cz/HTJbQ9K9cVNgFNcpc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpPu6-0000dv-S2@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:14 +0000

commit 49ed711a956e8bd0c634e1c030d4734eadad673b
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:08:17 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:17 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a194cbc76f..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55041.95737 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuH-000216-UT; Wed, 16 Dec 2020 06:03:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55041.95737; Wed, 16 Dec 2020 06:03:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuH-00020x-Rb; Wed, 16 Dec 2020 06:03:25 +0000
Received: by outflank-mailman (input) for mailman id 55041;
 Wed, 16 Dec 2020 06:03:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuH-00020q-1K
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuH-0007zM-0a
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuG-0000eb-Vw
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oBm1Dc7Mex068aRMDcHO1w9dBNw2qpIRouuQRyeHfns=; b=OReZp1nUg9qgDzGxeIui1AI2W1
	9+ucqVr7xlAFZuxlsZQKnGjEfJlvhN8aSj2Jc66yKL4AiDOE8ZHujhbW6rTA+r9LjjXN6VMIXVALg
	J1mZC21QMcGLzUmTNoB5vNKe3Wrd0bUEeypH5g/+2Qy4jvNbmwArNE5+xeBK/4AfwFGo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpPuG-0000eb-Vw@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:24 +0000

commit 7214cc7457a2862984039e96f21a5e03bfd16c50
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:08:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:21 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 505560a5de..56b5e4578b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -682,6 +682,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55043.95742 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuR-00022q-WF; Wed, 16 Dec 2020 06:03:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55043.95742; Wed, 16 Dec 2020 06:03:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuR-00022i-TH; Wed, 16 Dec 2020 06:03:35 +0000
Received: by outflank-mailman (input) for mailman id 55043;
 Wed, 16 Dec 2020 06:03:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuR-00022G-4B
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuR-0007zU-3T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuR-0000fC-2i
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=w61Yg7TYRuCP1PFgu8hLGqrNcT/E0FNo8HpKRZUUh9Y=; b=WlmhBmTONs+7Mgr5zwD/32i4tl
	JeeUyJAWh7Dz8kfrBsgz/a0sBtpSNQgnuXf9UN1OLfS8s5B3XvHzsnH4QQX4wIMVy6Jy0LGi9UtVn
	7Mfn4KgEELal1Ro0UsaoRPLMx7FF2yuuqJ9Pf7KFzWPAxb0NLMOHt95vVgbKSBnmkSbE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpPuR-0000fC-2i@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:35 +0000

commit 57bbcd069b8965edef34c86893563336b4552c94
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:08:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:08:32 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 56b5e4578b..1d05d25a48 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1346,6 +1346,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1404,8 +1430,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1462,14 +1490,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1485,6 +1513,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2171,8 +2200,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2184,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index eb19b71f5f..196a6fd2b0 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index dc635e9be3..d5e1e3e9d4 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -286,6 +286,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -303,6 +307,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55044.95746 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuc-000243-1b; Wed, 16 Dec 2020 06:03:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55044.95746; Wed, 16 Dec 2020 06:03:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPub-00023v-Uw; Wed, 16 Dec 2020 06:03:45 +0000
Received: by outflank-mailman (input) for mailman id 55044;
 Wed, 16 Dec 2020 06:03:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPub-00023o-77
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPub-000802-6Q
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPub-0000fi-5W
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DQCSCA1HuRgXSAPOw+f5jJ765bQh0FX6cvLW39q9vQo=; b=KJtROQvCkdzLceN2KPfJmPIoIN
	+zGQiiaTHsTcvFBy36rZ5C7vOcPwr6F8Qv/EGPOzYXsLYx+QlIaOGTzRDQBi5F26AcoOmmdVdXrj4
	thTnhdSrJQ7MWjAthnIZyyovaisvsJ+Yalf5eYXeCDsnzrEh7gRQaoxLQDQeQD3VuFiE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpPub-0000fi-5W@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:45 +0000

commit de822c4a2cc5fad708255d3589e6b05757055ccd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:09:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:09:10 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:03:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:03:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55045.95750 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPum-00025M-3B; Wed, 16 Dec 2020 06:03:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55045.95750; Wed, 16 Dec 2020 06:03:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPum-00025F-08; Wed, 16 Dec 2020 06:03:56 +0000
Received: by outflank-mailman (input) for mailman id 55045;
 Wed, 16 Dec 2020 06:03:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPul-000258-9t
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPul-00080A-9C
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPul-0000gN-8P
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:03:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1QchudKU3qgkgus2RU0Q4+NY/ktpo+jUwMxyW0kwwSE=; b=X9Ty8n4V6dUHfTdajFMcqkP+wk
	u1YlTEQD2BFge2+S58FP1gPWVrtpI1EydmEbVccX8E6OpSw1CRKz8EaGcGd7sGd+K7xgo9UfKyB0l
	cSwpqEFYoFWsVO72TdkEeH2E3QdZcICsWun7Vlq1HaTtFzhTD2euUytgcbLxTCGreHLc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpPul-0000gN-8P@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:03:55 +0000

commit 13268c50c0ee6fe7ea1ccc69965ec48c49f317c1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:09:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:09:16 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55048.95769 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuw-00028W-JQ; Wed, 16 Dec 2020 06:04:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55048.95769; Wed, 16 Dec 2020 06:04:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPuw-00028O-Fk; Wed, 16 Dec 2020 06:04:06 +0000
Received: by outflank-mailman (input) for mailman id 55048;
 Wed, 16 Dec 2020 06:04:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuv-00027H-EC
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuv-00080Z-D1
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPuv-0000hG-C5
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=keUr8w+pXNquu43TmUwYDzEEIvyAi6d3Tjl110/R0rc=; b=JchZ9zPEyeXm4Z8cs1hCU69hMJ
	3dyGg77vUEqJeuji34Z3ejmD2229oU96kHAfHoUU8Omp6UD8gQrZnM3KWW7z2yQkaT80+2t92GZup
	8etrdaKp4CLaEkGmdrJMQGwu7kt/obnEo+MTXE9yrlsHlEg/Ai8fYI0aXrGY3B1npQlI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kpPuv-0000hG-C5@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:05 +0000

commit bfc99c310fb156a4f0cacfd17c216207db8044ca
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:12:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:12:47 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
    master date: 2020-12-15 13:40:27 +0100
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c830d1225c..5114774f94 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 0c0c2a964e..ccdc4e004b 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1032,7 +1032,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ca94c2bedc..a71b935c10 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1909,7 +1909,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 44e4ea2582..92ed8a0292 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -113,7 +113,7 @@ static int parse_pcid(const char *s)
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index c9b6af826d..01d58e4879 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -676,7 +676,7 @@ static void __init noreturn reinit_bsp_stack(void)
         asm volatile ("setssbsy" ::: "memory");
     }
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 861a227dbd..81ceafce98 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1635,6 +1635,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 51a4cdbf7c..b47addb3c8 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,13 +155,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
             "jmp %c[fun];"                                              \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
@@ -176,12 +176,6 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55049.95773 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPv6-0002CU-LM; Wed, 16 Dec 2020 06:04:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55049.95773; Wed, 16 Dec 2020 06:04:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPv6-0002CM-Hg; Wed, 16 Dec 2020 06:04:16 +0000
Received: by outflank-mailman (input) for mailman id 55049;
 Wed, 16 Dec 2020 06:04:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPv5-0002Bw-Gh
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPv5-00080j-G2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPv5-0000iK-FF
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Siy824sjkvWCQCPTDFjdpQoZNwLi+wxVyuuwu4yOwtg=; b=kvv2tiGtwd5g1eN3vPQ2rWQW+W
	A36oE4ubYECxU/6lS2ueaZP6yrgWF071ILH5ezBhR4aclwApHxrbIs6KYlckYEAv6k09K6R3aXjDu
	GLXHHNh3EaBIwCQFwSU9o1lUAyvABGkGWTPy0U1ElNBcCqK9iJKXvgg4rFuakgMCN5WE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kpPv5-0000iK-FF@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:15 +0000

commit 5174e4202e1fdc145a661e6ad1762b9e1acdb27c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:13:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:13:19 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: 058e469ab4d5cc5959423aafd6ba181dfc310a7f
    master date: 2020-12-15 13:41:09 +0100
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 5114774f94..d47a483744 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55050.95776 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvG-0002Fl-Oo; Wed, 16 Dec 2020 06:04:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55050.95776; Wed, 16 Dec 2020 06:04:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvG-0002Fd-Lc; Wed, 16 Dec 2020 06:04:26 +0000
Received: by outflank-mailman (input) for mailman id 55050;
 Wed, 16 Dec 2020 06:04:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvF-0002FN-L5
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvF-00080q-KI
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvF-0000j2-Iv
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=CmfRNqcdKWbprtirQeqnLN4e7oRf2FisRkABI+jPyCY=; b=MxVaC1yqpOyK9Z4VIyFH43wXhh
	5RHeE92W8e+STx6wASL2aexm0i1viDsL2Jm+KoZoKreEzBM3bUkTXSWogUYwSgn4YDUP6DmnyWx8A
	XOZATfzKANKsc11FFqjENU+snJJUjuA3fmGtnqw5WpKgbigPC8H0hKzvlFgq6TqzApqE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpPvF-0000j2-Iv@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:25 +0000

commit d8f08a44bc8da1401a9731667daecdb9b213c073
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:13:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:13:56 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d47a483744..3da81ebf1d 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -535,7 +530,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1851,20 +1846,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index ccdc4e004b..90cdab3734 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -987,8 +987,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a71b935c10..1466064d0c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,8 +1850,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 92ed8a0292..fe3d22dce6 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,7 +110,7 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b47addb3c8..4d8822f78c 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,18 +155,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-            "jmp %c[fun];"                                              \
+            instr "[fun]"                                               \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
             : [stk] "r" (guest_cpu_user_regs()),                        \
-              [fun] "i" (fn),                                           \
+              [fun] constr (fn),                                        \
               [skstk_base] "i"                                          \
               ((PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8),               \
               [stack_mask] "i" (STACK_SIZE - 1),                        \
@@ -176,6 +176,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 40385f5eaa..0db551bff3 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -326,7 +326,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 111ccd7e61..09ea0fa2cd 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 struct hvm_emulate_ctxt;
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55054.95780 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvR-0002IE-Py; Wed, 16 Dec 2020 06:04:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55054.95780; Wed, 16 Dec 2020 06:04:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvR-0002I7-NA; Wed, 16 Dec 2020 06:04:37 +0000
Received: by outflank-mailman (input) for mailman id 55054;
 Wed, 16 Dec 2020 06:04:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvP-0002Ht-O0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvP-000814-NK
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvP-0000kZ-MU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=36U+W29trIcNUqLy4la1Tv6ZxgcmcIcTm0Mqghrcx70=; b=K9KzsraCKcCgkKGlxEfg5eJrri
	lVmi1TofMn9qwjJ/wlhRVKluDZV6KOQsB9a3Ro5ZPwZJarQc7fWdBd+BJlKjmO0Kv96YMWBHPgEua
	5MH6o+1yJmGSe3QPmGc5AsSxduM/utjVSAU1lTCHG8Mho/ppPVDnt1G1g90NuoTZG7Sg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] x86/irq: fix infinite loop in irq_move_cleanup_interrupt
Message-Id: <E1kpPvP-0000kZ-MU@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:35 +0000

commit d785e076b36111899ef9ee2340f2da9375afc9f5
Author:     Roger Pau Monné <roger.pau@citrix.com>
AuthorDate: Tue Dec 15 14:14:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:14:34 2020 +0100

    x86/irq: fix infinite loop in irq_move_cleanup_interrupt
    
    If Xen enters irq_move_cleanup_interrupt with a dynamic vector below
    IRQ_MOVE_CLEANUP_VECTOR pending in IRR (0x20 or 0x21) that's also
    designated for a cleanup it will enter a loop where
    irq_move_cleanup_interrupt continuously sends a cleanup IPI (vector
    0x22) to itself while waiting for the vector with lower priority to be
    injected - which will never happen because IRQ_MOVE_CLEANUP_VECTOR
    takes precedence and it's always injected first.
    
    Fix this by making sure vectors below IRQ_MOVE_CLEANUP_VECTOR are
    marked as used and thus not available for APs. Also add some logic to
    assert and prevent irq_move_cleanup_interrupt from entering such an
    infinite loop, albeit that should never happen given the current code.
    
    This is XSA-356 / CVE-2020-29567.
    
    Fixes: 3fba06ba9f8 ('x86/IRQ: re-use legacy vector ranges on APs')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
    master commit: ca85682e8c16361fdf3814c9b25a2ec3ff4f8bed
    master date: 2020-12-15 13:42:16 +0100
---
 xen/arch/x86/irq.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 8d1f9a9fc6..37c86283cc 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -441,8 +441,15 @@ int __init init_irq_data(void)
     set_bit(HYPERCALL_VECTOR, used_vectors);
 #endif
     
-    /* IRQ_MOVE_CLEANUP_VECTOR used for clean up vectors */
-    set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
+    /*
+     * Mark vectors up to the cleanup one as used, to prevent an infinite loop
+     * invoking irq_move_cleanup_interrupt.
+     */
+    BUILD_BUG_ON(IRQ_MOVE_CLEANUP_VECTOR < FIRST_DYNAMIC_VECTOR);
+    for ( vector = FIRST_DYNAMIC_VECTOR;
+          vector <= IRQ_MOVE_CLEANUP_VECTOR;
+          vector++ )
+        __set_bit(vector, used_vectors);
 
     return 0;
 }
@@ -727,10 +734,6 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
 {
     unsigned vector, me;
 
-    /* This interrupt should not nest inside others. */
-    BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
-                 APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
-
     ack_APIC_irq();
 
     me = smp_processor_id();
@@ -774,6 +777,11 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
          */
         if ( irr & (1u << (vector % 32)) )
         {
+            if ( vector < IRQ_MOVE_CLEANUP_VECTOR )
+            {
+                ASSERT_UNREACHABLE();
+                goto unlock;
+            }
             send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
             TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY,
                      irq, vector, smp_processor_id());
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55055.95786 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvb-0002Ji-Sa; Wed, 16 Dec 2020 06:04:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55055.95786; Wed, 16 Dec 2020 06:04:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvb-0002JY-Oo; Wed, 16 Dec 2020 06:04:47 +0000
Received: by outflank-mailman (input) for mailman id 55055;
 Wed, 16 Dec 2020 06:04:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvZ-0002JM-Qt
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvZ-00081Y-QE
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvZ-0000lD-PR
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bF+yBtIbQFdbdV0oC2tZvfrpKO0M6JABEJPkuurAiJY=; b=sB5LdJd0hs6Nb8v49UUpYfGT9w
	6Bc7hXAuBetbc1ae1VmFSOSYPaR0B8XaUkTFNvF9rK8GLdz7sCBOsG6hPL+j7WxwUBMsrLMgznts+
	vqrf4fKLDTcF9b26Im1l/97JjrtlDPsnAqYwxlYqxQ+7bKgG2LMbDfxtOSn8NcFDwsiM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpPvZ-0000lD-PR@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:45 +0000

commit 9872981ddd8483190f5f634e289806ee047d3f5c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:14:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:14:54 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 06:04:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 06:04:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55056.95789 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvl-0002LD-TF; Wed, 16 Dec 2020 06:04:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55056.95789; Wed, 16 Dec 2020 06:04:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpPvl-0002L5-QM; Wed, 16 Dec 2020 06:04:57 +0000
Received: by outflank-mailman (input) for mailman id 55056;
 Wed, 16 Dec 2020 06:04:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvj-0002Kq-Td
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvj-00081g-T0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpPvj-0000lr-SH
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 06:04:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1v5fNhQs0LhYEAYsn1GoKDnGmwEqWQdBFOXVzgWjpFc=; b=IsRnPXky05G0TtretlOXoDdMxf
	Ny5T5G2SN69eAZ8apqWAzXwdMaGp2UyBjbcRWQ1NvT5UGflZqi2nhbTKxysHiN8BxzMPo83cWu1lp
	0dFYyE6u/KUv169wsyETd/wFqLLijohr0rTQ4hkpizD+xidTF1rw6iCftPh22OhO5ylc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpPvj-0000lr-SH@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 06:04:55 +0000

commit d17a5d5d2774601f8137984a3ee23ec28eb0793c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:15:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:15:13 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55139.95952 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTlv-0001Mv-Er; Wed, 16 Dec 2020 10:11:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55139.95952; Wed, 16 Dec 2020 10:11:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTlv-0001Mn-Br; Wed, 16 Dec 2020 10:11:03 +0000
Received: by outflank-mailman (input) for mailman id 55139;
 Wed, 16 Dec 2020 10:11:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTlu-0001Mi-IL
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTlu-0004ME-GS
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTlu-0002Xs-ET
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+Wlv+6O7y+LzrVcNu6Qm+kLgDftvL6K/agzeUlhPuNQ=; b=SbDzNbLJC96Oqh7s1+bzYeN6Nw
	/NrPN01H47892MCVVnuZJe7xriD00MatH6B/s+eO7aqw/Kihvzov3TFJtBrg6ZVBUiX55EZ/v+qkl
	lxyxDDKV6Y2YsDmNYkDnAmttPPmRm4+wSiL5JARY4m1rq8IaicJgFGrub91aM+7x+gqA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpTlu-0002Xs-ET@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:02 +0000

commit e8231b61b22b8836f40b2f86394b52242b36c4c4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:42:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:32 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 5a8c377603..6375a1c889 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55140.95956 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTm5-0001Nk-GW; Wed, 16 Dec 2020 10:11:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55140.95956; Wed, 16 Dec 2020 10:11:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTm5-0001Nc-DQ; Wed, 16 Dec 2020 10:11:13 +0000
Received: by outflank-mailman (input) for mailman id 55140;
 Wed, 16 Dec 2020 10:11:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTm4-0001NV-LN
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTm4-0004MH-KZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTm4-0002YW-Ig
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+jxeWDKiEvrBInDVGp3nQICPwuhb1NA7fu+ay+nQCj8=; b=PLGAR/3yIDEaPh0hSXzpNYhx3G
	0zKmnGBwvVeDWA/P0Ot3vLmAcF3eNsONTC/eugMdv4dFApf+71W+khzYV+AqsEM5FjLQcKCYeqyRY
	ULhnfhSzkVp1b20Y1KOMOirv22yew88tHTpjinPxtbcchroEbVyJL3e9zI+Lfusqljaw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpTm4-0002YW-Ig@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:12 +0000

commit 3afd3844aa0af868357c9ab2152b76d0ba261477
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:46 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3d7eb91254..ee312378f7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -151,7 +151,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55141.95960 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmF-0001Pc-JG; Wed, 16 Dec 2020 10:11:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55141.95960; Wed, 16 Dec 2020 10:11:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmF-0001PU-GL; Wed, 16 Dec 2020 10:11:23 +0000
Received: by outflank-mailman (input) for mailman id 55141;
 Wed, 16 Dec 2020 10:11:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmE-0001PI-Pk
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmE-0004MQ-OZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmE-0002ZH-Mk
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bOr1fWPnLBQhSPq6x+9la6fAiFIUTvD6L72k2KIE8AA=; b=vmATTOX6YWnT3OA3FvXQ0mm+tb
	+cYqWwgvCgSFmw6s56rhvft50Soirrz1xCoKx2RD+FoJXXh46yIkguCv6noOMh1LbUh2/eAt8vjNF
	K4kgjPhdMqKzYU44ic7iRioPhtmEH97lxkFMnYx4VkdyqhDMhi95hkvOnZz7jLrIwkwA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpTmE-0002ZH-Mk@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:22 +0000

commit a043a64bd9415042e680a10ac75c34dc4fe08240
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:42:52 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55143.95964 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmP-0001RC-LI; Wed, 16 Dec 2020 10:11:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55143.95964; Wed, 16 Dec 2020 10:11:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmP-0001R2-Ho; Wed, 16 Dec 2020 10:11:33 +0000
Received: by outflank-mailman (input) for mailman id 55143;
 Wed, 16 Dec 2020 10:11:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmO-0001Qt-TT
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmO-0004Mc-Rv
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmO-0002a2-Qd
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PbW70+SmyrQwnSCtoVTYGEku/g7VlFIhzIGuN/B+q1Y=; b=4PArJ/ByP1BQf1K+gEwIsy7HD5
	hkKEtu8NgdsnOYHR536hlvXYMhGbGpg04bWctwlk95wpeIu+tIF7vSuWtK4wH/Hmr66jKvkS9e9zD
	8VvPDkJqEaniIUuAxYA6gcHS1BOtXbov02wbT5G8g6O2cfWWHjKG+pyImjnMzc+s/v9k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpTmO-0002a2-Qd@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:32 +0000

commit 77d6b2b600dfcfe274ec6a553c3fa700c8b6cac5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:03 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55144.95968 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmZ-0001Si-MF; Wed, 16 Dec 2020 10:11:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55144.95968; Wed, 16 Dec 2020 10:11:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmZ-0001Sa-JL; Wed, 16 Dec 2020 10:11:43 +0000
Received: by outflank-mailman (input) for mailman id 55144;
 Wed, 16 Dec 2020 10:11:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmY-0001ST-Vc
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmY-0004N3-Un
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmY-0002ak-Tx
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zuqHWJSqsJ6ZOwDo5uoMEqZPndd5TbeW6w49QMzxRG8=; b=GmoHSU+hh+eIYlMO/zkr4gba35
	QttfT4ipLcgGIJvPaBAlhRG5Pzf7mNvJfS1kvpBVl96JyeEZbC1z0TpywmZaduSMrD+X8MnmzKDdW
	P4lFs5iaNrZXcPyj/lVHhiH/W41wtEi7d4AlLKWYIkoxPDQAab1IqFsNQAmla7f3RX58=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpTmY-0002ak-Tx@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:42 +0000

commit 06092d1f96354d75f91d2acd04c0c1232f2b9eec
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:07 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:11:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:11:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55145.95972 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmj-0001Tw-O1; Wed, 16 Dec 2020 10:11:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55145.95972; Wed, 16 Dec 2020 10:11:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmj-0001Tn-Kx; Wed, 16 Dec 2020 10:11:53 +0000
Received: by outflank-mailman (input) for mailman id 55145;
 Wed, 16 Dec 2020 10:11:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmj-0001Te-2T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmj-0004NB-1b
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmj-0002bM-0m
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:11:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Z3hkNEb7tIZyxEc3EnKiNU549JhnT9s2gXnqT57DomM=; b=xnmhZWbdKfz9pnxutgqzlaJnv1
	hacU5Q1y02mPLneci6PmEtG/dztgaz7YJGWP/XB7CdbJOByHehShSZPHiu016gySWXD8jHGdBTCQQ
	DDvVZHZG2d0K8TBvAKS/5FmPZUAXB4ARoA07tXcX12bL6HDWFizqKP8Tj2KRFVyuErok=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpTmj-0002bM-0m@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:11:53 +0000

commit 2fee46c8d74e16647b7b1f63cac42efa26a77dbd
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:12 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55146.95976 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmt-0001Wj-Q2; Wed, 16 Dec 2020 10:12:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55146.95976; Wed, 16 Dec 2020 10:12:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTmt-0001WZ-MW; Wed, 16 Dec 2020 10:12:03 +0000
Received: by outflank-mailman (input) for mailman id 55146;
 Wed, 16 Dec 2020 10:12:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmt-0001WS-5b
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmt-0004NZ-4v
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTmt-0002c8-3m
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=CfgpOeumLlOg1ll5H55dwDjHRNsE5yz88oaHtErtW4A=; b=sZH7c+pGC1slHZDKPox9RXSJGp
	GNTMrdwhXQKVQpOYSQNks+jljT5KAtysstohk1hZ8omniKl2ZI7V1IZshYeqFF5jqxUI5egM+3PXu
	+kbjmbSWt7g2pHPG0VV76/BN2DrhLxGqezViZoTkdFsQyIgQQtShxwMyp3ihPCur7Bas=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: rework node removal
Message-Id: <E1kpTmt-0002c8-3m@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:03 +0000

commit 8cb4d2d2d60f367b0f1722ba3d5de98b93c33ee7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:18 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55147.95980 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTn3-0001YC-T1; Wed, 16 Dec 2020 10:12:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55147.95980; Wed, 16 Dec 2020 10:12:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTn3-0001Y4-Q1; Wed, 16 Dec 2020 10:12:13 +0000
Received: by outflank-mailman (input) for mailman id 55147;
 Wed, 16 Dec 2020 10:12:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTn3-0001Xy-8h
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTn3-0004Nh-80
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTn3-0002cm-75
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4T3B3muB9ioAhiPL+BJlE4n77hkwUsP6EuzP4Niy3ow=; b=QikCo1UQbm4XfwXzlBidQw43VP
	nmsbuW62puV/9KT28QMEyVgOz2mf2XXfvJSwkReI9siSRlHt7moG5z39XN201K8J797latqBQATcc
	vKZa3C6mz04jMwuzejuWBcichXnChoOQ4hYePw9OxJgBAt2uGnOTJiVRLVIv+KdyeUBc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpTn3-0002cm-75@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:13 +0000

commit 9edd614ef8dcd6339a8ccd6c1e38c224c5711f1c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:22 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55148.95983 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnE-0001ZY-UV; Wed, 16 Dec 2020 10:12:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55148.95983; Wed, 16 Dec 2020 10:12:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnE-0001ZR-Rc; Wed, 16 Dec 2020 10:12:24 +0000
Received: by outflank-mailman (input) for mailman id 55148;
 Wed, 16 Dec 2020 10:12:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnD-0001ZH-Bs
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnD-0004Np-B7
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnD-0002dm-A9
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AR1n1hMxbqUd4zEnBxB5PZVDMJnsUjqWo2P5qrteScw=; b=AADNR3twwljBWzR2iiW94Q0i/a
	/IIOYSeeW89qhlFXCdfAwNIyOELzoYv6FnSmQ5BqOotwSPQTe19wAjQlhLFvzXOem/VUstRRdvuod
	Bv/Gjhh1EdZzdzjDDTc5bDhRQcFE5gjNdcmZRR1n2J44r+G2oSb71k2T39o0yfi/12yI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpTnD-0002dm-A9@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:23 +0000

commit 36580444463dbac63de5b6b4218910df5492eef9
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:28 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ee312378f7..a43bb55530 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -111,6 +111,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -122,8 +127,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55149.95988 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnP-0001ak-0G; Wed, 16 Dec 2020 10:12:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55149.95988; Wed, 16 Dec 2020 10:12:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnO-0001ac-TN; Wed, 16 Dec 2020 10:12:34 +0000
Received: by outflank-mailman (input) for mailman id 55149;
 Wed, 16 Dec 2020 10:12:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnN-0001aS-F8
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnN-0004Nv-EQ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnN-0002eO-DT
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=g0eAgKp9IFf1WsI0sUGIyp9Uw6v6Zh9BcgBer7bPckM=; b=nLz5TnhlX/dV/nUTIEwx9ZvXgb
	1Ddc0GGuKOV8A4Qit1vbwHpGCaNlqpuV0WSxdNZIVx6lgWnHaBKzFFF3dzraZnfAdJBajSeTO+YL5
	dL1tzn5TfnnvornXztR4Aw2a7rDkpwmoVbJppmc40GRsoRf5GgQ9WONVBwHE1Up1vPPg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpTnN-0002eO-DT@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:33 +0000

commit f06e4ac53f409216b53b0d8824ab44fadeb6cf55
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:33 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a43bb55530..2092067502 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -167,6 +167,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55150.95992 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnZ-0001cJ-1v; Wed, 16 Dec 2020 10:12:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55150.95992; Wed, 16 Dec 2020 10:12:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnY-0001cA-Uw; Wed, 16 Dec 2020 10:12:44 +0000
Received: by outflank-mailman (input) for mailman id 55150;
 Wed, 16 Dec 2020 10:12:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnX-0001c2-Ia
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnX-0004OM-Hq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnX-0002fD-H2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xh7AodXhMIToF2A/vxfoLYJlc1ASBOQusDkw3wQhtMk=; b=QeQbebaYJCp1IETLJEqYY+Jmx3
	lv/35/+YmnsSR2zVFAn+CLn/FlWNcuXjUp/dO8JIIljJgeTi3Hk6kTM2eHj5f+qOX7396+NKfSTPY
	YKWphz7KQ0fGZkEvtc0sSL6c7wxSi5EoVESMxLbrKC2Iht2sSa88/goRSk2SJSFnT6cQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpTnX-0002fD-H2@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:43 +0000

commit 03937f9928452325400bde39212f74a2a9fe0a88
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:38 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2092067502..e4966c89e3 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -154,15 +154,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -173,6 +175,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:12:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:12:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55151.95996 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnj-0001dk-5h; Wed, 16 Dec 2020 10:12:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55151.95996; Wed, 16 Dec 2020 10:12:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnj-0001dc-2m; Wed, 16 Dec 2020 10:12:55 +0000
Received: by outflank-mailman (input) for mailman id 55151;
 Wed, 16 Dec 2020 10:12:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnh-0001dT-M8
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnh-0004OU-L3
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnh-0002fq-K4
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:12:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zepHreIh2B1XaD48b0lCpDXCu4c+Ig127VxxT5o9XH8=; b=GTqTSX2QEYh2W+vUjk3HjZsDdT
	89FGQN3iJrgdgH9fULh7or1XsYgERp+Y2bZxlqUmazswANTVkgJKyErLSybrv9MvyxRpyfBUmaqdD
	Xje/Rw1NfB7xGBPwirm8ajZS8gSPTW4ynKN8Hu3FEAhrcqS3YKPnCllGLvTAtsgDra+Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpTnh-0002fq-K4@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:12:53 +0000

commit 57a55a429bb58a39c470a25826e65e1fc4ebf50c
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:43 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 74c69f869c..0a0e43d1f0 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55152.95999 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnt-0001f5-79; Wed, 16 Dec 2020 10:13:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55152.95999; Wed, 16 Dec 2020 10:13:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTnt-0001ex-4H; Wed, 16 Dec 2020 10:13:05 +0000
Received: by outflank-mailman (input) for mailman id 55152;
 Wed, 16 Dec 2020 10:13:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnr-0001el-RW
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnr-0004Ot-O2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTnr-0002gk-NG
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=M9S7LJzZ0Be7/5UDbRUv35bhngtGMGB7VbMm1AAsgQg=; b=Op+vzixNq6Kcdm+oyDJMlM5BXr
	kevEcz8nxw0Ei1xLUJVvC+8InipwGS9swycJHJTIxXPg8buDNEdo9nL7ByGXGFy7VW7ntNR9G/O9l
	hPjjfpAxYQHdF3UeJYnj9rMsUdAfRl1f/yw/LQ4nH2L1xyCXyi+uNijjOoY9KSFZ0rd8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpTnr-0002gk-NG@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:03 +0000

commit 59dc712c72076fb778659aaba40da5d623fe8ee1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:49 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 0a0e43d1f0..f374abe998 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t domains cons data =
 let do_error con t domains cons data =
 	raise Define.Unknown_operation
 
-let do_isintroduced con t domains cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55153.96004 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTo3-0001gG-8v; Wed, 16 Dec 2020 10:13:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55153.96004; Wed, 16 Dec 2020 10:13:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTo3-0001g8-5o; Wed, 16 Dec 2020 10:13:15 +0000
Received: by outflank-mailman (input) for mailman id 55153;
 Wed, 16 Dec 2020 10:13:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTo1-0001fy-Rm
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTo1-0004P3-R7
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTo1-0002hU-QB
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=LiV4nOJDlEp49qYXDjyXwY5hF8g8kbPM38sAJClVtxQ=; b=TCtovlKPzlYczseCyzUBGFqDrY
	kBJl77ZzgnHPOXpydaRNRMi/CsPaOAZER9CvjQnRQDtjo5XAijCMACKHuvaCO/2LrOLVnfuWp2KDY
	Xin1r9T990I4bFGP89Cr61P+asGPzOAe9fXTlSbxIjYP6eTSO5pzezNj8jsqvMJCYpyY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpTo1-0002hU-QB@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:13 +0000

commit bdd36b63225a3be7cf9a686847dee4d0c1678094
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:54 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index be9c62f27f..d7432c6597 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55154.96007 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToD-0001hU-AI; Wed, 16 Dec 2020 10:13:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55154.96007; Wed, 16 Dec 2020 10:13:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToD-0001hP-7I; Wed, 16 Dec 2020 10:13:25 +0000
Received: by outflank-mailman (input) for mailman id 55154;
 Wed, 16 Dec 2020 10:13:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToB-0001hD-V3
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToB-0004PC-UA
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToB-0002iF-TP
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=PaX5t6gzsQQIGXEJ+bPx93M24uDUcM44hr3pYQkFC8w=; b=lTed4qxwaC49rPhdNaD/44SkQI
	5IC8NKaKQjIvi5X3l85tw31/rUqiQCXJxFANQ+w8WxqPk7jatdBaRpG0AFeeAyFvQ3LWGFrCw4E3Q
	79pgyuw6Ab7xQpy9H3/XTgxU23T+E98w6C/Q6J8eTERepEpCCrBlMADHUmkyeyhMxaMU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpToB-0002iF-TP@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:23 +0000

commit a4c2c94e8ba8e9dd99b98b9dbe5f112baa76c1c5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:43:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:43:59 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f374abe998..c3c8ea2f4b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6375a1c889..98d368d52f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e89c1aff04..f3d95e8897 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -89,19 +89,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (String.sub buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 49fc18bf19..32c3b1c0f1 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55155.96012 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToN-0001io-Cf; Wed, 16 Dec 2020 10:13:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55155.96012; Wed, 16 Dec 2020 10:13:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToN-0001ig-8y; Wed, 16 Dec 2020 10:13:35 +0000
Received: by outflank-mailman (input) for mailman id 55155;
 Wed, 16 Dec 2020 10:13:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToM-0001iW-24
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToM-0004PK-1O
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToM-0002it-0Q
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YsjDUSSWhb+C5M2jIQQV5yJNqQXMaoAR7ScyY8sI7WI=; b=VIqgD+AUT6gqT3u+3W/ys5Ggh2
	iWL/Ah0J/vZbNfsRjVwdbA6ZoYapc69eQD71oQSmaxDo08FQmFZrvVAQxq0948xeSmL74GMvno863
	gUUOYh8rNRnsCXBWtERzQW1aVV8q+vcjPz/VzhWqMI/auu+/nFxTOLpADLSD3hkxJiw0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpToM-0002it-0Q@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:34 +0000

commit 7e16a0e884c245fbe34cc6bfe047230a432dbbd5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:03 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 ++++++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 ++++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++++-----
 tools/ocaml/xenstored/process.ml     | 36 ++++++++++++++++++++++--------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 84 insertions(+), 28 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index d7432c6597..1389d971c2 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index ae7692819d..020b875dcd 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec x = function
 		| None         -> ()
 		| Some watches -> 
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index 0c0d03d0c4..fab76829cf 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -333,3 +337,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index c3c8ea2f4b..3cd0097db9 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			Connection.end_transaction c tid None
 		)
 
-let do_watch con t domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) = 
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con t domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -414,7 +419,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +438,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 23e7ccff1b..9e9e28db9b 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 32c3b1c0f1..e9f471846f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55156.96016 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToX-0001kc-Ev; Wed, 16 Dec 2020 10:13:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55156.96016; Wed, 16 Dec 2020 10:13:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToX-0001kU-Bx; Wed, 16 Dec 2020 10:13:45 +0000
Received: by outflank-mailman (input) for mailman id 55156;
 Wed, 16 Dec 2020 10:13:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToW-0001kL-5C
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToW-0004Pu-4T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToW-0002jk-3d
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1po44vjUcALl43LACMSvW4h/OOCp4M8wrdxLSpFkSMA=; b=VczC6b93or0PUUt1LkY92PM7z6
	k+xptn8MW5zWVVT+64MVLKq40ZnoJ3/3cZl+KZM8zm04NgEsLyVVhCp2OnItcQ0fX+9t/N2n7M2G7
	gD6+tMrWgzjx4JnowZ22KMy2AWHNhEqyQrYNyvhGX3PosJM8sDo2pE+qL76/54btk5pQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpToW-0002jk-3d@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:44 +0000

commit e644edc7f2b6e58a70cd4668bf9fa482d5154bb5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:08 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 1389d971c2..698f721345 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 6579b84448..d5d4f00de8 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index e9f471846f..30fc874327 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:13:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:13:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55157.96020 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToh-0001lq-Gf; Wed, 16 Dec 2020 10:13:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55157.96020; Wed, 16 Dec 2020 10:13:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpToh-0001lj-Dc; Wed, 16 Dec 2020 10:13:55 +0000
Received: by outflank-mailman (input) for mailman id 55157;
 Wed, 16 Dec 2020 10:13:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTog-0001la-88
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTog-0004Q2-7T
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTog-0002kX-6g
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:13:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vBij1TvN5bcrScBlBX/RyrooHobsMDg70NM24pQP7dQ=; b=66+/J4E+y/Q9K45GjzToYH21mM
	Uzs2YRpHJBNKuF7/7hNAjbA/WE/LGvLv1Yi30Kn2oILX7tEcPocyurxG/zzjzEbyS4Nuda2mH6ZXp
	8tNCRGlYBqNIBKToYIiGhNMWu6OJIuywIPSsQLyfm7zLoABIxg2aOfIOJGMlJrZwgRss=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpTog-0002kX-6g@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:13:54 +0000

commit fcc17dc279d76a00dfd3d7a5c0537c32f928002b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:44:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:27 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..4fbe5c759c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..f5e7af46e8 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -301,58 +323,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -399,15 +447,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -518,8 +572,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -662,8 +716,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -744,6 +800,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55158.96024 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTor-0001n7-J3; Wed, 16 Dec 2020 10:14:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55158.96024; Wed, 16 Dec 2020 10:14:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTor-0001n0-FO; Wed, 16 Dec 2020 10:14:05 +0000
Received: by outflank-mailman (input) for mailman id 55158;
 Wed, 16 Dec 2020 10:14:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToq-0001mq-Ch
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToq-0004QN-C3
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpToq-0002ld-9Z
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=EVUchFFtYYcxHUyEU3swcEhgMsCy5RjWxaAOzdroIX0=; b=FpcmtTH6Dd1FGL1Z6YCFyv5xPh
	i7CNMJ9Neb7rUvNCnjaKp0aWNlwB1vDJiwf5mV+WfZMGjE8gh0rz15UtWICooSqNpzZnreCC94ipt
	B4z9WSs8fpoBoCmY8CxZ8v6HscfWiJ5J58XWlEPyfly7qx72hninxZjn58dXh/yYsNAQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpToq-0002ld-9Z@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:04 +0000

commit 66e2db1d6ed6dc261658931547454c8065ca9287
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:44:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:44:32 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 3cd0097db9..6a998f8764 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches 
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 98d368d52f..6bbbd05552 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 30fc874327..183dd2754b 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55159.96028 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTp1-0001oh-LG; Wed, 16 Dec 2020 10:14:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55159.96028; Wed, 16 Dec 2020 10:14:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTp1-0001oZ-IN; Wed, 16 Dec 2020 10:14:15 +0000
Received: by outflank-mailman (input) for mailman id 55159;
 Wed, 16 Dec 2020 10:14:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTp0-0001oQ-Fd
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTp0-0004QV-F0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTp0-0002mT-EH
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0tr1UOMGXS5xL6HaFBrfUkiGm+crGLE+lDm5QVQ6uo4=; b=x4Vr1LgGwkazDrHVgv/lAkWUFq
	ahjhwkUZErDwvtpLg4ORRfxaLYsVyArck+xtdmfDgJA2T/vhW0aiZOQJBVaACust4VZsceiOCFNX5
	3DXr/BOkqDYwuMZ55lS/OqlbmadupB5Fj+p1DUXXd36081NkKUUZM1KUD+o+IhfpaayI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpTp0-0002mT-EH@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:14 +0000

commit 17b26b823b00a2993ea3f7517bff2e236c939103
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:01 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 6 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index d5d4f00de8..bef633090b 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index f3d95e8897..02639c77e9 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -94,7 +94,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -102,4 +102,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 183dd2754b..70f1bf8d2e 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55160.96032 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpB-0001pt-Ms; Wed, 16 Dec 2020 10:14:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55160.96032; Wed, 16 Dec 2020 10:14:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpB-0001pl-Jr; Wed, 16 Dec 2020 10:14:25 +0000
Received: by outflank-mailman (input) for mailman id 55160;
 Wed, 16 Dec 2020 10:14:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpA-0001pb-Im
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpA-0004Qd-I5
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpA-0002nD-HF
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Mdz6ESQ0ZaBHGbGdP3K6E1sFJrVX7zjnWd7816YEsXs=; b=DmzNpIv25sEth4LaqaWC/k1n31
	lUBdpR85iNKR250WSqOCPDXa+XuXlFUN9EcTjmra+PEFebsCfi7ODOEYhcdaCjCh3zs5w9GKjNeqm
	u9LanW4Dve6BociNanyY6VHkzOJ6bpblfqXAMGOUnYNzpHWEGuHtOKpGdttnPCytUj0g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpTpA-0002nD-HF@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:24 +0000

commit 03569ab92888b2ca217747ac5d58aa1259fb0c6a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:45:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:08 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 4fbe5c759c..e8f2057a32 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55161.96035 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpM-0001rH-OS; Wed, 16 Dec 2020 10:14:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55161.96035; Wed, 16 Dec 2020 10:14:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpM-0001r9-LU; Wed, 16 Dec 2020 10:14:36 +0000
Received: by outflank-mailman (input) for mailman id 55161;
 Wed, 16 Dec 2020 10:14:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpK-0001qz-Lf
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpK-0004Qn-Ky
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpK-0002o8-KD
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dLVH6SmAhba1AbSuxn9qz6uVGKLrYPZI5xVT89rGayM=; b=2yMeVycpqnt9w3eOfpy1Fx6wbN
	kZo7eo1qLaF1FPBhWScNjlK82KF3GY90brBiGhfmtFvENnUegxm9PUkcetOKhhHG3J3rMlygGNQIB
	8k/sdHMKCzwHjh9tfm4JY7KeU6OnER8nf1OnF8nUVzMZu+GD/jPkI2S0rO113PdZuvs0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpTpK-0002o8-KD@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:34 +0000

commit 3056f89163d8ef7a56a6c1881519d4abc6193685
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:45:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:13 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index e8f2057a32..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index e4966c89e3..6d1d0460b4 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -82,6 +82,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index f5e7af46e8..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -298,6 +298,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -315,6 +319,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55162.96040 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpW-0001sl-Q0; Wed, 16 Dec 2020 10:14:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55162.96040; Wed, 16 Dec 2020 10:14:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpW-0001sd-N6; Wed, 16 Dec 2020 10:14:46 +0000
Received: by outflank-mailman (input) for mailman id 55162;
 Wed, 16 Dec 2020 10:14:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpU-0001sS-OU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpU-0004RH-Nr
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpU-0002oy-N7
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ijLq/UqAqZdJdqdIBXYpgSbDYMXAWO7Hn5vwwumNPno=; b=rAaS4SMCyzNWih1MVAmGbJN2om
	uD7g/RgYCy5PxF6P4G6zBJXq2c3PEaORrA1Y8PI82vXrhSmcZ5nJzYTvwY7ojGrGoYckgGvnuMVWL
	bj1Q1nloQRNTlHH7l3FoxMLiUydRzbp6AQ4L4jUh2z0S9EDU9lpHay99cjtvp0mMD1Kg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpTpU-0002oy-N7@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:44 +0000

commit 7073b82830378bf21137e57357cb1c1cf6f8954d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:35 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 020b875dcd..4e69de1d42 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 6a998f8764..12ad66fce6 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con t domains cons data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:14:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:14:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55163.96043 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpg-0001u2-S3; Wed, 16 Dec 2020 10:14:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55163.96043; Wed, 16 Dec 2020 10:14:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpg-0001tu-OZ; Wed, 16 Dec 2020 10:14:56 +0000
Received: by outflank-mailman (input) for mailman id 55163;
 Wed, 16 Dec 2020 10:14:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpe-0001tj-SK
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpe-0004RS-Qs
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpe-0002pq-Q0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:14:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kBc5BlAYn7t7kbR7XYvOgIWYxVxEYUGFR+Z4pa8+WjA=; b=6NeHVhTz6sz33Ia5zo9Ygn7EvG
	mEoWyBP8gaFjPtW77V/w9Czscas6OmwaWoBukP4pDxkl/9eDBb0k80k5hgrPX/l/3It6YCsyWY8fG
	oeQJDD4s8g4pFCr4zhlLtkJrsmno+pDfmEilzp0uMz0Ntvwr8VjUmpFpxcjVfTeIdzj4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpTpe-0002pq-Q0@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:14:54 +0000

commit fef52f19ed59bbb379b04a711079c67aaaf788d4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:45:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:45:47 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6bbbd05552..2a694562bb 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:15:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:15:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55164.96047 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpq-0001vV-Uc; Wed, 16 Dec 2020 10:15:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55164.96047; Wed, 16 Dec 2020 10:15:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpq-0001vN-Rf; Wed, 16 Dec 2020 10:15:06 +0000
Received: by outflank-mailman (input) for mailman id 55164;
 Wed, 16 Dec 2020 10:15:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpo-0001vB-Uu
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpo-0004S0-UH
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpo-0002sM-TV
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xsYJwKrNGs4eITHPywCxOetTzGVtG+zVB1d9AFUypgs=; b=Xcic31rNkZ58VXjZQ1gN20953l
	i+r2xYaR3Ml1tJxajo/LhnINI880uegXR8pJzFTIPy5Ql+CsVSHbZfn7vo3qLMy5qlBh3M46ezNnJ
	cweiODpe11GxIB3m6N5ULuASzlP+zHqHckStEiVz00RJTWCTOSRyZrsKZFp2Q5+s5IWg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpTpo-0002sM-TV@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:15:04 +0000

commit cbc06ee4280371f78f5858cd613c8d1e2a53ecd3
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:46:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:46:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 7ae7266c5f..2c59863342 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -121,7 +121,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -161,11 +161,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -560,7 +555,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1765,20 +1760,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 25fc9f2288..0365d6bfc2 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1086,8 +1086,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(hvm_msr_tsc_aux(v));
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     bool_t debug_state = v->domain->debugger_attached;
     bool_t vcpu_guestmode = 0;
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index e18ebbae9e..a500117781 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1785,8 +1785,9 @@ void vmx_vmentry_failure(void)
     domain_crash_synchronous();
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
 
     if ( v->arch.hvm_vmx.active_cpu == smp_processor_id() )
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 22269023bf..8834190feb 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -64,7 +64,7 @@ custom_runtime_param("pcid", parse_pcid);
 #undef page_to_mfn
 #define page_to_mfn(pg) _mfn(__page_to_mfn(pg))
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b7860a772f..2c15df54bd 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 5afaf6b9de..bd31fada49 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -330,7 +330,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
     /* nestedhvm: translate l2 guest physical to host physical */
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index aad25335eb..a05a0d4d62 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:15:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:15:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55165.96051 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTq0-0001wh-0M; Wed, 16 Dec 2020 10:15:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55165.96051; Wed, 16 Dec 2020 10:15:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTpz-0001wY-TH; Wed, 16 Dec 2020 10:15:15 +0000
Received: by outflank-mailman (input) for mailman id 55165;
 Wed, 16 Dec 2020 10:15:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpz-0001wR-2Q
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpz-0004S6-0y
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTpz-0002tH-0E
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=t3pHan4JGxkna4X/H2+2equGKjvPpNg4D/Qwe+8GolY=; b=e9FGDKylD1qBwsxC3+9AtzZuww
	1dEMWFuwjnaGaUBd29sHQNhrk6ztpSeDDJiAhaJ70tVLFseSetjwuEPfvtWyj+5nLSC5rZMWq0I1j
	A7Jelq94RyOmtepgdGaaJWQOG1lNNhyEH9+jVSo0cXBPxdDbFZhCFTAG20WQaUtIuyHE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpTpz-0002tH-0E@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:15:15 +0000

commit 136ac884e621a74b6b6168f474ae751a0ec690ab
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:47:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:47:04 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 0a90a8404d..ab9e496696 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -227,6 +227,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -452,6 +456,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -462,10 +467,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 10:15:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 10:15:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55166.96055 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTqA-0001y8-1K; Wed, 16 Dec 2020 10:15:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55166.96055; Wed, 16 Dec 2020 10:15:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpTq9-0001y2-Um; Wed, 16 Dec 2020 10:15:25 +0000
Received: by outflank-mailman (input) for mailman id 55166;
 Wed, 16 Dec 2020 10:15:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTq9-0001xt-57
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTq9-0004SG-4V
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpTq9-0002u7-2w
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 10:15:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=21ld0p8LZlo52KrDe6OekyJfuVidx6USLRfmZ5W7U8E=; b=isQ1ZFQpmeEl/z2YiLqyKYlY3v
	GX2uWIx9O5nZkBJkkwqQEPs2ap6X2SNqjNCRbRCjOo9tb2GipJ+M2Mj7CC6mZT+ooaeKzGkJvsz0I
	cNuMUxi+nd2LaTNvf+TzN9CYQdvbL1soyyXF5E6B/zOalryZB3M+Zvj8cJkaoMu5PUVc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.10] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpTq9-0002u7-2w@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 10:15:25 +0000

commit 6ea37c69c7d3948d9bb6f217235ae8bd767e8c46
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:47:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:47:28 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index ab9e496696..454ca40743 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -590,6 +597,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.10


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55217.96153 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKe-0000I0-KX; Wed, 16 Dec 2020 12:55:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55217.96153; Wed, 16 Dec 2020 12:55:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKe-0000Hs-Ha; Wed, 16 Dec 2020 12:55:04 +0000
Received: by outflank-mailman (input) for mailman id 55217;
 Wed, 16 Dec 2020 12:55:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKd-0000Hn-8C
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKd-00073Y-3l
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKd-0005o0-2G
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=UfhVotMVnT9I9QRvbxcHAxjeZt+oNsaTAoBd8B+PZbk=; b=L30I6ANrh8uZeNKHptHv+QPoSi
	KzfP/HA0cvqM0BPKTaMMPWdNwWL+nMne54MN45dcKEq2DVVS4/Z8e7voHhXlJcIxaYqJli2JEuNCn
	V1gqgOZ5xnbwYftWRujRxh1RG3VU5rz4Xx53NEAYpS9HTDNwkaaJj9xQ1ZriATHdDDuw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kpWKd-0005o0-2G@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:03 +0000

commit d2b6bf98ee27b266025e48b3c537a639a5c72609
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:35:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:35:00 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 5a8c377603..6375a1c889 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55218.96157 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKo-0000Iw-MQ; Wed, 16 Dec 2020 12:55:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55218.96157; Wed, 16 Dec 2020 12:55:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKo-0000Io-JC; Wed, 16 Dec 2020 12:55:14 +0000
Received: by outflank-mailman (input) for mailman id 55218;
 Wed, 16 Dec 2020 12:55:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKn-0000IT-7j
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKn-00073b-6w
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKn-0005of-5y
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HFb+ptqKS1Y6ryQ9peCv2Kpa9cb3z7Os0kDw7ORKbCE=; b=pInVdcQbdHZ/fsFtnYXJajK3QK
	wnQ4oBbfu/K+O7X+T46ZQbuSzcKVYCNRCvu12UEOwOI+aNdEOb7AIwggv0bAFp+lo5Wy/qDSsMBMf
	g80NTXhxkV/0fEzhxPKRPO3DcGzMOAwionQ1+kjbUAakus5NhbKsWhuSewFwJzTKsOME=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kpWKn-0005of-5y@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:13 +0000

commit 029777015c93e64830eea07e4a4c3bb23601d5c0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:02 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3d7eb91254..ee312378f7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -151,7 +151,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55219.96161 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKy-0000KN-Nj; Wed, 16 Dec 2020 12:55:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55219.96161; Wed, 16 Dec 2020 12:55:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWKy-0000KF-Kl; Wed, 16 Dec 2020 12:55:24 +0000
Received: by outflank-mailman (input) for mailman id 55219;
 Wed, 16 Dec 2020 12:55:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKx-0000K7-B6
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKx-00073p-AQ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWKx-0005pY-96
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WlscK/+69o4PRSmxsDmLXWs3mWQjDlugjMV8k08UP/g=; b=LG8uvVBFoUsrY7znsD+fyYJJbD
	SFHUa9p/I+Rv+5WvMsO8+2R7XQDuBZas4bboMkNzmjGjEoCKLMYpked3zjYlM6KwKiz3uZFy1602o
	g+C4Jh6uRV5RlX9M1dKP2XZZBKiNorxjXrCS0UeuAP7GEGTsyzm93U29cjXVPwbwwpZE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kpWKx-0005pY-96@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:23 +0000

commit 550387fe857adcbc2e84fe4c159d84223909f6d5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:08 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55220.96165 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWL8-0000Lq-Pe; Wed, 16 Dec 2020 12:55:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55220.96165; Wed, 16 Dec 2020 12:55:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWL8-0000Li-MO; Wed, 16 Dec 2020 12:55:34 +0000
Received: by outflank-mailman (input) for mailman id 55220;
 Wed, 16 Dec 2020 12:55:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWL7-0000LY-EF
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWL7-00073z-DW
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWL7-0005qE-CZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ajzkrJUZjlZSn9la10Ya6te0HGcJfGEQPgrwo+CXVoQ=; b=qOjeYRHrU+8MYQELIVhv0kjNSw
	uKeqv/rk/dj542R4pF3zSw4CJJF78YBsUcq57L8kIfZApy2+xMsSKJzefsD5p+1pRx/oEMGhA0/ao
	IRyvg4QxCRBTkkrMTw9QsVBht+SLuhX/2uHHOZPn+wTUh06oKQjaFpMh7jfu8IMjo+cs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kpWL7-0005qE-CZ@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:33 +0000

commit 170445fa3c2511c7a20555be2082c7db5e1e9d97
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:12 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55221.96170 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLI-0000Nk-Re; Wed, 16 Dec 2020 12:55:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55221.96170; Wed, 16 Dec 2020 12:55:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLI-0000Nb-Ns; Wed, 16 Dec 2020 12:55:44 +0000
Received: by outflank-mailman (input) for mailman id 55221;
 Wed, 16 Dec 2020 12:55:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLH-0000NT-HC
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLH-00074S-GS
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLH-0005r1-FZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=CMX0qdAG41Fccsi0Y3zCegAJJyiY94ZREIGY+vINU0o=; b=vQNVgYoKo0j/TWqD+v1ZyAO6p0
	tpXa2jYNxjrLpgGOjhSDVE9QbGjqS8lWcmZljFn07+r5qPb73+Ym2deUToSqQLc81E6GcJ230gaUW
	ljoVOZNj2Yef+c4OA8b0bvzcWhWyO7sooSeQM12jLIKLaXYKeDNpH1PwRb17nvth+9dk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kpWLH-0005r1-FZ@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:43 +0000

commit 88f6ff5d551b14c2e83a72196f5a95f3f27ce46a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:17 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:55:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:55:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55222.96172 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLS-0000P2-So; Wed, 16 Dec 2020 12:55:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55222.96172; Wed, 16 Dec 2020 12:55:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLS-0000Ou-PR; Wed, 16 Dec 2020 12:55:54 +0000
Received: by outflank-mailman (input) for mailman id 55222;
 Wed, 16 Dec 2020 12:55:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLR-0000Om-KV
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLR-00074a-Jk
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLR-0005rl-Il
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:55:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AnSn7JjXMaUKZl3x+z3KN4YXyFcQ3PzZ1orWiwNVhv0=; b=jbJs84kalEoi4xngMFWjDEhZNa
	DJqV7ZyzeElh3PH8FVfj1iMCXVI1LdRgFOgnpKItzfHexunUAX7kSA0LZ0ta7vGWnDtGMyNmKHLST
	DU8OKfBI0mjzUPhvN9x7adDNfECPpxONQHTKJs36RVPKbzIAkJO4GX+lkyPtUaqtK91A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpWLR-0005rl-Il@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:55:53 +0000

commit 36621b760bce6446204d82f365ee7c5c7361934b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:21 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55223.96177 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLe-0000QW-00; Wed, 16 Dec 2020 12:56:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55223.96177; Wed, 16 Dec 2020 12:56:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLd-0000QO-T5; Wed, 16 Dec 2020 12:56:05 +0000
Received: by outflank-mailman (input) for mailman id 55223;
 Wed, 16 Dec 2020 12:56:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLb-0000QD-O8
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLb-00076S-NQ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLb-0005sb-Ls
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=IQNQ92Zs1tpo/butMmIzTLfja0VHghoL4TQRati2tT8=; b=GfPnDJRtVTElX7g893y9NMwV9G
	LBlevTMUk8o9PXhXL6NoAkt5HldDmHvicABYeVjaB3CiPEFqkdFGx/VQs1mhYWgHLUZK5mU3bi0D3
	jWZf2gyzQOwy2H01q7Rntz/MqzL85DOIE/mG73jd4ZWqXdhA41YOYYOaBFcAnbkcp51s=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: rework node removal
Message-Id: <E1kpWLb-0005sb-Ls@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:03 +0000

commit 2fe5a55559a1813354a70f52a4d9548a49313cea
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:26 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55224.96182 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLn-0000Ri-1o; Wed, 16 Dec 2020 12:56:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55224.96182; Wed, 16 Dec 2020 12:56:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLm-0000RY-UZ; Wed, 16 Dec 2020 12:56:14 +0000
Received: by outflank-mailman (input) for mailman id 55224;
 Wed, 16 Dec 2020 12:56:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLl-0000RQ-Rb
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLl-00076Y-QP
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLl-0005tJ-Pa
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=70Vw5m1fKQU3XME7UFXTenHVQkkv/pgDlxcfRn/1CF4=; b=qwmaLkNdP4K7YMwUCIgwrV1iLl
	OAsehjl+7NTYbqOTpi41F++Ot4tqmW2xXeSxftjvnlBydruUfgJtr2hyG0DbZkDM3n75QSucUzEfh
	wA+kAawp6HwofYsLnIgCjv37VQT4HBn4yoFPixssdUwsRrXVAac+OqJ7Mssz5ISxALlQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kpWLl-0005tJ-Pa@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:13 +0000

commit 6be47ee3a408cf801945312a24f00f5c35e06eff
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:31 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55225.96185 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLx-0000T4-3C; Wed, 16 Dec 2020 12:56:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55225.96185; Wed, 16 Dec 2020 12:56:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWLw-0000Sw-W9; Wed, 16 Dec 2020 12:56:24 +0000
Received: by outflank-mailman (input) for mailman id 55225;
 Wed, 16 Dec 2020 12:56:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLv-0000Sn-VM
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLv-00076g-Tl
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWLv-0005uB-SZ
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FNEH6J8Lg62trAZHLkqyhvYgYID+ASQrES3cWFTPkWU=; b=YrohNLRI7Yv0PtMhOw//CyA8GB
	R13jMz/w1ecrc9TjLxL86bXvo5KwEhC1oLUXGbVb0PpZBgVyAmbM9bfFLQYYAUKneXDVl0MSWlh3D
	whihFiUJfWeokPHmYd6cZl5PJnk+wC7CdbiwZom5ZjRGzZEGQNuycvcq8Y6DEafIVv5k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: introduce node_perms structure
Message-Id: <E1kpWLv-0005uB-SZ@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:23 +0000

commit 0a6bbf99b4313e7def669d5b5e2f4e2f4d0b4720
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:36 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ee312378f7..a43bb55530 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -111,6 +111,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -122,8 +127,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55226.96189 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWM7-0000UJ-4i; Wed, 16 Dec 2020 12:56:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55226.96189; Wed, 16 Dec 2020 12:56:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWM7-0000UA-1R; Wed, 16 Dec 2020 12:56:35 +0000
Received: by outflank-mailman (input) for mailman id 55226;
 Wed, 16 Dec 2020 12:56:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWM6-0000U2-1h
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWM6-00076n-0a
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWM5-0005v5-W7
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vGJNP4clR2OQXFM4XDFhARx5KIEGXsqNkGWrQDc7scQ=; b=MAyH9poYx6WLaTk1Ow1M9ScRcl
	mulyOo/xQO5BMamUomtEiniVCmmaX1cB+oO9z4pvGn33YaHBNirWIwb+0bQsZfaqrLNa/B9ND4Q1A
	Z3/ceT0HrgWoaTAGwo9YbHORaFPehx3u5OQcukV+CvolvbH4dtebZDhJaxLU1sAM1thM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kpWM5-0005v5-W7@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:33 +0000

commit 1b7ed67cfafcbcba7aace46607cd36255a86606f
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:41 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a43bb55530..2092067502 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -167,6 +167,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55227.96193 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMH-0000W4-7Q; Wed, 16 Dec 2020 12:56:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55227.96193; Wed, 16 Dec 2020 12:56:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMH-0000Vw-4M; Wed, 16 Dec 2020 12:56:45 +0000
Received: by outflank-mailman (input) for mailman id 55227;
 Wed, 16 Dec 2020 12:56:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMG-0000Vo-4Y
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMG-00077A-3c
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMG-0005vm-2o
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1QKF/qygiZ8yH8p4PKmP0BfArOjmz93RJtUVroEpcTs=; b=aq2Jzxu4XWDvPoEGhR0KPtP8KW
	3YpHPlLbJjRjp2iwAlOBhLCtC9aUWHmBbDueLM159cqsHTI2KE2HkLCBf8y6PoLGpRC4PTEcLIhvu
	JzSic2rNJAZ1uPIguclfJEqdyXrSa05Bc4J/PqK37IkdcGxn41l1BJLYRCEVaZAp5rQ8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kpWMG-0005vm-2o@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:44 +0000

commit 57261ac3434c304f5c96cbb2da5cce8493a7662a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:46 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2092067502..e4966c89e3 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -154,15 +154,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -173,6 +175,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:56:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:56:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55228.96198 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMR-0000YM-9l; Wed, 16 Dec 2020 12:56:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55228.96198; Wed, 16 Dec 2020 12:56:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMR-0000Y2-5w; Wed, 16 Dec 2020 12:56:55 +0000
Received: by outflank-mailman (input) for mailman id 55228;
 Wed, 16 Dec 2020 12:56:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMQ-0000X5-7a
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMQ-00077H-6t
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMQ-0005wZ-5e
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:56:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KCjVhS8BNr2rD3N7OYlunmu04PjcEFhCOfqnHeETOAs=; b=X8xLA8mDrZ6mnqlV7kLkmPoo3W
	fP//YTVyPp9zlOKeJu6pEr9RTKw2t52P0obz9cLC8StgZah0kFD6C726iSNaxuwb9/xmwSw8q8VPR
	Fq87GbhAJgkStQb/esE4hTEOFxNLKuajsaDLOg/xwOxkEX+fUtz1gvTXJzbOorcmB7dc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kpWMQ-0005wZ-5e@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:56:54 +0000

commit 966f266be0806f3fa95b4c42e8e60fc2ee9f1da8
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:36:52 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:52 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 74c69f869c..0a0e43d1f0 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55231.96216 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMb-0000db-O5; Wed, 16 Dec 2020 12:57:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55231.96216; Wed, 16 Dec 2020 12:57:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMb-0000dT-L6; Wed, 16 Dec 2020 12:57:05 +0000
Received: by outflank-mailman (input) for mailman id 55231;
 Wed, 16 Dec 2020 12:57:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMa-0000cw-AS
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMa-00077j-9n
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMa-0005xZ-8v
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=NcCNwJE3Gmo4f4LrHHcKbWY7xH/Ut3xffYbgFDgclwg=; b=Q7H9JauSiLyMtxdpl8GC7O4XRC
	4I1d5ECd6pfRMTvoV+65O/MP8yGYhYiHEXcMYEWr+spzDcRXXp9r3PI+63F8MVkhWjsNzKcDcN2Nu
	aw4lFx9TP+NG3aRaHc/kqcMrRSThuOBHtyHohNYQttgQmt3obZg5kn2uQ7HUUDjevWOc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kpWMa-0005xZ-8v@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:04 +0000

commit b3f80a38b907e27cf9af6aae10f96594074ba363
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:36:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:36:56 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 0a0e43d1f0..f374abe998 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t domains cons data =
 let do_error con t domains cons data =
 	raise Define.Unknown_operation
 
-let do_isintroduced con t domains cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55232.96221 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMl-0000gU-Qe; Wed, 16 Dec 2020 12:57:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55232.96221; Wed, 16 Dec 2020 12:57:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMl-0000gI-MX; Wed, 16 Dec 2020 12:57:15 +0000
Received: by outflank-mailman (input) for mailman id 55232;
 Wed, 16 Dec 2020 12:57:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMk-0000g2-EX
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMk-00077m-Dq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMk-0005yP-Bq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=SfJXLIcaIVm3k8/+Z1vn/sD5Y+tQWQSMBDNB5zHDzZU=; b=J6bIRVIULYMDNx9Uks4uHmeImv
	LJLrnx5I/fXrm6wXF6xM0qkNvo+Qas87X0x7LPTVe5UgNs4E7/Ltu+R2kneu978JbfQ6AgMGYh11O
	5EWUerFGqGgfZipb1DF1nvcwt3pz0WEvWvDSYd4jrkXUG8ZyyvQ7z7P7adj9TNOmktOc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kpWMk-0005yP-Bq@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:14 +0000

commit 771a105b2880e6b40098d7a303400b3525a95df1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:00 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index be9c62f27f..d7432c6597 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55235.96224 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMv-0000j0-Rx; Wed, 16 Dec 2020 12:57:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55235.96224; Wed, 16 Dec 2020 12:57:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWMv-0000is-OM; Wed, 16 Dec 2020 12:57:25 +0000
Received: by outflank-mailman (input) for mailman id 55235;
 Wed, 16 Dec 2020 12:57:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMu-0000if-HI
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMu-00077u-Gh
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWMu-0005z8-G2
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Az0KXzx62vWRBg9i1aZzTbPHxqGSZVlJIRaITwHJEXM=; b=iS4ulU5zLq4J5RNyQKF4U8UaEi
	JrdC5J7N0uCoAYjtATIn2fttvxQeIh6ZfhF3fvjRZQMom8E8j7i2MCUq5c/tjIsCjt4IrWpJwwjix
	rJguG3lFqedVY/1FYiZNFePceFCpWeHQbfkCvPNXi/NROcUOK1EK4ohl/6YQYt4EW5o8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kpWMu-0005z8-G2@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:24 +0000

commit 495e97365a88a09c3479812c6428a5ec8a1418fd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:05 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:05 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f374abe998..c3c8ea2f4b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6375a1c889..98d368d52f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 49fc18bf19..32c3b1c0f1 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55237.96229 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWN5-0000kv-VI; Wed, 16 Dec 2020 12:57:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55237.96229; Wed, 16 Dec 2020 12:57:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWN5-0000ki-RU; Wed, 16 Dec 2020 12:57:35 +0000
Received: by outflank-mailman (input) for mailman id 55237;
 Wed, 16 Dec 2020 12:57:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWN4-0000kT-KU
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWN4-000782-Jm
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWN4-0005zr-Iv
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yP0NpuQrzacIwfO2fM9bhb0iw7ZEnlfb65RyYj+molg=; b=4RTaSf6+AU3YunwmFEHNP0gD42
	wpX6ZcG3xpVGb/0iu4rb8CdRx4yahRL/5gT60q0jhUEg/6bAwfTjFe+BCkufG8rlZxTK/Oczh8RBh
	3PKzegxOkRh7nFt/Vb1vUYuKYxzCxysg0oy1Orcpa+FaUs982KnwpUHl5Wy4cuhRr3wU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kpWN4-0005zr-Iv@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:34 +0000

commit 57244315c445aca68672b15c7a74a8152634668f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:10 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 ++++++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 ++++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++++-----
 tools/ocaml/xenstored/process.ml     | 36 ++++++++++++++++++++++--------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 84 insertions(+), 28 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index d7432c6597..1389d971c2 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index ae7692819d..020b875dcd 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec x = function
 		| None         -> ()
 		| Some watches -> 
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index ea6033195d..99c7bc5e13 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index c3c8ea2f4b..3cd0097db9 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			Connection.end_transaction c tid None
 		)
 
-let do_watch con t domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) = 
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con t domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -414,7 +419,7 @@ let do_introduce con t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +438,7 @@ let do_release con t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches 
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con t domains cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 23e7ccff1b..9e9e28db9b 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 32c3b1c0f1..e9f471846f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55239.96232 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNF-0000mU-Vy; Wed, 16 Dec 2020 12:57:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55239.96232; Wed, 16 Dec 2020 12:57:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNF-0000mM-T8; Wed, 16 Dec 2020 12:57:45 +0000
Received: by outflank-mailman (input) for mailman id 55239;
 Wed, 16 Dec 2020 12:57:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNE-0000mC-NN
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNE-00078U-Ml
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNE-00069k-Lw
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cT/rbGzdxi49Ok99/ZAWumu/aHZrL2C3v2fvGnzcuew=; b=ciNwe1Sp0MIAx/i5pOKRcwoSQy
	ulE+67EVH5ViU/hg1NeV8CrmXoxiQTnlOs1KzK8CbvM4giwCf5wmfibugAJDjX5AdPliYf8zaP65p
	sbK8Vai56atfldmDX2HPi8/bZnkMyqzF4SlXNWTJssOGGhTCtfAd8iCym51fiF4R9WLU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kpWNE-00069k-Lw@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:44 +0000

commit 7791d2ed24daa1cc108139790e6fc0bcc927794f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:15 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:15 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 1389d971c2..698f721345 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 6579b84448..d5d4f00de8 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index e9f471846f..30fc874327 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:57:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:57:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55240.96235 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNQ-0000nw-1o; Wed, 16 Dec 2020 12:57:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55240.96235; Wed, 16 Dec 2020 12:57:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNP-0000no-Un; Wed, 16 Dec 2020 12:57:55 +0000
Received: by outflank-mailman (input) for mailman id 55240;
 Wed, 16 Dec 2020 12:57:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNO-0000nf-Qa
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNO-00078c-Ps
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNO-0006AW-P0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:57:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=c7v4CcsMIn2hzpxQaG07YC0qEA5UM3X4KbASY4ls/oU=; b=k0bUYYqwQ/wFEz+AUFVsCeoGlT
	No+YcyKfd4fdmODEewLB+H60oNTyhftG1yXJz8vLpgIhnR8iPjQKRSuYQ1GX9nD0XWuncTsLuzBWx
	ns0DZO1Ta5siuWnUgCkupDvzY2myA5SwtRsdw2cNWDdiXrFVkw71O45tlLXGcrKDW7dk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kpWNO-0006AW-P0@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:57:54 +0000

commit 1034a45d2da1b9ff5b02235b3bf8458b238b9e98
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:37:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:43 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..4fbe5c759c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..f5e7af46e8 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -301,58 +323,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -399,15 +447,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -518,8 +572,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -662,8 +716,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -744,6 +800,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55242.96240 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNa-0000pk-4z; Wed, 16 Dec 2020 12:58:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55242.96240; Wed, 16 Dec 2020 12:58:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNa-0000pd-22; Wed, 16 Dec 2020 12:58:06 +0000
Received: by outflank-mailman (input) for mailman id 55242;
 Wed, 16 Dec 2020 12:58:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNY-0000pS-TV
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNY-000793-Sq
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNY-0006BI-S0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DXuOQyaLUStFwxQnyeIIIzhCbLGDEtgAnTYSc9EzXUM=; b=k0IRr1SLa+cnknpm1377SOFjzV
	RuwRyiv55OmhXZyPqS336/3cxrpIZ8oXFIw2nUdk+OvObglciNRqnQSN23soF5ww9C0CoXq4ETGqU
	5amxNDRdI2CUuNzy+y8ZpA2ZAzKJpkzMzOj6Cc+XwmpDirv9Dz5RRAERDK4QgmHNyJC8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kpWNY-0006BI-S0@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:04 +0000

commit e36f81fc8efe841f90a3aa69f809ea3ae95888a5
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:37:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:37:48 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 3cd0097db9..6a998f8764 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches 
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 98d368d52f..6bbbd05552 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 30fc874327..183dd2754b 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55243.96244 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNk-0000rK-6l; Wed, 16 Dec 2020 12:58:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55243.96244; Wed, 16 Dec 2020 12:58:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNk-0000rC-3o; Wed, 16 Dec 2020 12:58:16 +0000
Received: by outflank-mailman (input) for mailman id 55243;
 Wed, 16 Dec 2020 12:58:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNj-0000r3-0D
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNi-000799-Vo
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNi-0006CI-Uv
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=uwtV/7HFkSLoVVd+XoFRYXE5fkgQByQm1Xp6ouhfs0k=; b=EEnSX4R4QvTl9y5oLvNnEoTg7B
	GFDpHhYW3kqOFf87JWJyEBtp25gXJkW1wasCnn5udVYVj5nzr9k5tp/4XUTTqAGjrp6mt03k4vR0F
	TahR36UIcFNnnuWNse5peNmfyvb3QoOXP0E9CxtWupNb/bxbdDEZ5AnQBnbnkvqr1c+A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kpWNi-0006CI-Uv@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:14 +0000

commit b3f4121ba2be9f995d3416719c0eb367a4d10fa3
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:04 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index d5d4f00de8..bef633090b 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 183dd2754b..70f1bf8d2e 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55244.96248 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNu-0000si-8E; Wed, 16 Dec 2020 12:58:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55244.96248; Wed, 16 Dec 2020 12:58:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWNu-0000sa-5J; Wed, 16 Dec 2020 12:58:26 +0000
Received: by outflank-mailman (input) for mailman id 55244;
 Wed, 16 Dec 2020 12:58:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNt-0000sS-30
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNt-00079K-2J
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWNt-0006D9-1e
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=X2jcI+7EgPn2imj+NPoOIx/dURA7WgQLBli9ksXKFK4=; b=nEUGFXqgyFXc/QaVUqBZRsTYNc
	qbEAZCDlJYvVp1gj7iEqA6ddvFZ33pNd6/4bmOyXI+8dva09H0t9h6BYgghYjpPQmkTsCcS73QExc
	ayZ0gmGLgcQ0G2Ct5Uqtbgztw3YSQMergZfWJm1ICVnidxljJLbMRzvUXbKxQRFLMKOA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kpWNt-0006D9-1e@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:25 +0000

commit 40537713d604ef8065e09fa3eb606b3782b0d3f0
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:38:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:09 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 4fbe5c759c..e8f2057a32 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55245.96253 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWO5-0000uF-A3; Wed, 16 Dec 2020 12:58:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55245.96253; Wed, 16 Dec 2020 12:58:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWO5-0000u5-6v; Wed, 16 Dec 2020 12:58:37 +0000
Received: by outflank-mailman (input) for mailman id 55245;
 Wed, 16 Dec 2020 12:58:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWO3-0000tr-60
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWO3-00079R-5L
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWO3-0006Dk-4W
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0POVuCygfhJVVs9IunO5fsU43ma/1xp1ASW192UIYn4=; b=JtfDDjOTwpqd4YDrSQrZLRj2Th
	6d30pWBsxaSjn6FAGPWx925K9mDyWwSj7g+GJZ4wL0AGpH51WA5yVEKnGOxwDTamGWDr3vYT5v1U6
	dfAmYwJ+3ph9r4oZFBk5qhQo78wnJ8avGke6C+r6kcZGq2hkMNaCSw9I/lo+5QWV1duk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kpWO3-0006Dk-4W@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:35 +0000

commit 4cc23870318f01c1fbd33159b3351c8128df49a1
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:38:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:14 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index e8f2057a32..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index e4966c89e3..6d1d0460b4 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -82,6 +82,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index f5e7af46e8..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -298,6 +298,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -315,6 +319,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55246.96257 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOF-0000vr-C2; Wed, 16 Dec 2020 12:58:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55246.96257; Wed, 16 Dec 2020 12:58:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOF-0000vj-8M; Wed, 16 Dec 2020 12:58:47 +0000
Received: by outflank-mailman (input) for mailman id 55246;
 Wed, 16 Dec 2020 12:58:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOD-0000vS-8l
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOD-00079v-89
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOD-0006ER-7S
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=b7BpoGW7zqAPIXECdQOMBolQ+pn7okWkDErOpRfV+TY=; b=UEeOq8bh7tgkclPXpbH2/qGa82
	gs8zj8+6KAWciVuwK+rK3x/H0qZJxLGP80oCtsmUQUIFXvjxUUEvaYAwtxKBhErQbDxZWwZAZXeF0
	23gk2yPaIXxt77vgrOTYU9EWK5cpvX4A6x9nHizbB6VLWrLtY4O7YQFPT1Ez682f0Jes=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kpWOD-0006ER-7S@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:45 +0000

commit 1e870589fac5717761a44d9da52e95decd45c4ae
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:42 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 020b875dcd..4e69de1d42 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 6a998f8764..12ad66fce6 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con t domains cons data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:58:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:58:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55248.96260 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOP-0000xT-Ec; Wed, 16 Dec 2020 12:58:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55248.96260; Wed, 16 Dec 2020 12:58:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOP-0000xL-Bm; Wed, 16 Dec 2020 12:58:57 +0000
Received: by outflank-mailman (input) for mailman id 55248;
 Wed, 16 Dec 2020 12:58:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWON-0000x7-Bb
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWON-0007A2-Az
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWON-0006Ev-AD
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:58:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=v8mQwG5EAVd1rJsTKX6KuUV/XR4OrSjzOOpo1REKASk=; b=cwjXv6GkvIsxatWnhicAWyTKCC
	E77tB7+T4JSDUoeeXjgU+WB+7l0JjF6kEWltwzjspjoH2/GDqEiHcvpCnB+qhNZg06mP20gu/6Vwl
	BvZoVjRJTcMoazlN/5fYZb8Zv5LvIzFH23oDa/9xysymPg5YjT2pk2yfzNZ4WWUYxels=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kpWON-0006Ev-AD@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:58:55 +0000

commit f1f3dee7477a8f4e5b17a0025bbb77f0f3a9e3dd
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:38:47 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:38:47 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 6bbbd05552..2a694562bb 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:59:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:59:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55249.96264 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOY-0000yh-Gb; Wed, 16 Dec 2020 12:59:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55249.96264; Wed, 16 Dec 2020 12:59:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOY-0000yV-DJ; Wed, 16 Dec 2020 12:59:06 +0000
Received: by outflank-mailman (input) for mailman id 55249;
 Wed, 16 Dec 2020 12:59:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOX-0000yN-F0
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOX-0007AR-EO
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOX-0006Fe-DX
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7RGEAyuJ0VnFuYUHKpP3vlBuJifkykpYU0UxYWBCbM4=; b=YsJqMPMBWwi6b9lU3l778cIlwA
	cdUG6awl63tZPQbc3waOJXSKclLPWZO4tL4KUMxbDMA74rPqyuwQgYb5xxDSjQRwTHW7A3cV2bTNP
	5ojrKGkD5HXz3bn8xn/Q1ZiRu3GjfHOPO5F48lH5TweV0aLwexCYXHt+gXJ3GlW5RQis=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kpWOX-0006Fe-DX@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:59:05 +0000

commit 24f7d0305aed5a9657202bb8b4927dfbebca82a2
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:39:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:39:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 35857dbe86..5182ca388f 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -121,7 +121,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -161,11 +161,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -456,7 +451,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1764,20 +1759,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 2f8aed8cb9..8adc39cc92 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1111,8 +1111,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(hvm_msr_tsc_aux(v));
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 332f2d810d..e2019aae7c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1782,8 +1782,9 @@ void vmx_vmentry_failure(void)
     domain_crash_synchronous();
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index c6461cdcd5..5d373c371f 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index f3508c3c08..cab3c6ff97 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 360c38bd83..045a563756 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -328,7 +328,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
     /* nestedhvm: translate l2 guest physical to host physical */
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 20eb7f6082..36663bb307 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:59:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:59:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55250.96268 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOi-00016E-Hy; Wed, 16 Dec 2020 12:59:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55250.96268; Wed, 16 Dec 2020 12:59:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOi-000166-Ex; Wed, 16 Dec 2020 12:59:16 +0000
Received: by outflank-mailman (input) for mailman id 55250;
 Wed, 16 Dec 2020 12:59:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOh-00015y-J1
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOh-0007Aa-IN
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOh-0006GE-GS
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7Fzgt+myAP8vfvnpaeNJmEwKNnPzVv9Qfb/49K6gFlc=; b=VmpY6mWLCF4Z90zG/ZJummK5WT
	vNH7JeFgZlTpYoR/eH+q1kbleQCnCydMM45Gq09ccT+vdFh2lbCxYOGrIPOpryqMjBdTiQsaW0YPX
	F+FxsVksevFQKkjs0pvaV8SvLh7bVAQ9pLXBZuumZGKu1+afqpo7KASbqXFuedIcVfHw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kpWOh-0006GE-GS@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:59:15 +0000

commit 2d4982550da86ecd50a4c4b0b558bd2a3911514b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:40:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:40:12 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 0a90a8404d..ab9e496696 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -227,6 +227,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -452,6 +456,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -462,10 +467,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 12:59:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 12:59:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55251.96272 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOs-00017V-JZ; Wed, 16 Dec 2020 12:59:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55251.96272; Wed, 16 Dec 2020 12:59:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpWOs-00017M-GZ; Wed, 16 Dec 2020 12:59:26 +0000
Received: by outflank-mailman (input) for mailman id 55251;
 Wed, 16 Dec 2020 12:59:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOr-00017E-Lt
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOr-0007Ah-LF
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpWOr-0006Gw-KV
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 12:59:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=84aLn2V7JJkkFMllX+uqTEAgUhUC9/zhytduzL16XV0=; b=3hxV6wXPcnLF/Kiw57sO4m8S/w
	fvy+yRtwcDdcoxrGD2ujeTz7C8TRqVT35Ov/53AgMrODy6rmtnq2kFWCYZ4/lcWpAHaANTenIuqFc
	WFi3rTRwQxnvUypaVWSdH0+AkcFbq6EyeqYGnYuqTnmxOxgioe7Ig15wnzQrMcq801eM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.11] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kpWOr-0006Gw-KV@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 12:59:25 +0000

commit 310ab79875cb705cc2c7daddff412b5a4899f8c9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:40:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:40:35 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index ab9e496696..454ca40743 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -590,6 +597,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 15:55:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 15:55:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55316.96391 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ8s-0001Is-LY; Wed, 16 Dec 2020 15:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55316.96391; Wed, 16 Dec 2020 15:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ8s-0001Ik-IX; Wed, 16 Dec 2020 15:55:06 +0000
Received: by outflank-mailman (input) for mailman id 55316;
 Wed, 16 Dec 2020 15:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ8r-0001If-6O
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ8r-00022C-2g
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ8r-00045Q-0E
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qdo1BkXOP1jmptc8vonR+kEkwumObkPD6RahgygxjJs=; b=EId3NrdmsXi7zlFADCa4HIcQMp
	s9QCcHxd8tKajoMHgM++KeXIIn+TJVem2117/5XRU7qzJ9VADVrIlM8uI3cfs2208YcYx1WgttqGO
	eujFUAsYM5B0nr9DWrlMquXA92IlUQftaW6VCNRKrClRciN7hbj2KPg4m7/OdfmYwI/A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86: clobber registers in switch_stack_and_jump() when !LIVEPATCH
Message-Id: <E1kpZ8r-00045Q-0E@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 15:55:05 +0000

commit 033a80677087b322789d2748e83b764545f76c6b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:41:46 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:41:46 2020 +0100

    x86: clobber registers in switch_stack_and_jump() when !LIVEPATCH
    
    In order to have the same effect on registers as a call to
    check_for_livepatch_work() may have, clobber all call-clobbered
    registers in debug builds.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/include/asm-x86/current.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 4d8822f78c..231994a245 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -120,6 +120,14 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 
 #ifdef CONFIG_LIVEPATCH
 # define CHECK_FOR_LIVEPATCH_WORK "call check_for_livepatch_work;"
+#elif defined(CONFIG_DEBUG)
+/* Mimic the clobbering effect a call has on registers. */
+# define CHECK_FOR_LIVEPATCH_WORK \
+    "mov $0x1234567890abcdef, %%rax\n\t" \
+    "mov %%rax, %%rcx; mov %%rax, %%rdx\n\t" \
+    "mov %%rax, %%rsi; mov %%rax, %%rdi\n\t" \
+    "mov %%rax, %%r8; mov %%rax, %%r9\n\t" \
+    "mov %%rax, %%r10; mov %%rax, %%r11\n\t"
 #else
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 15:55:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 15:55:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55317.96395 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ92-0001Jh-NH; Wed, 16 Dec 2020 15:55:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55317.96395; Wed, 16 Dec 2020 15:55:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ92-0001JZ-KB; Wed, 16 Dec 2020 15:55:16 +0000
Received: by outflank-mailman (input) for mailman id 55317;
 Wed, 16 Dec 2020 15:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ91-0001JN-7L
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ91-00022I-68
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ91-00046X-4q
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=XI4TmnLOJwmLZnGy0WaasNpozqtn5m/acq/1l1+wiz4=; b=BXDC9zBtzO7dRJttgG1c6GP8kc
	QgDcTlOQY/m8mEy9Yd3ID2Awo5ceUX8Vsr+9kL1PF4ii/99KDRF8Zu8vSPo62CVKKPpCHOTowWmmy
	2eBx+sth/q8FOIZ29OBrYMe7ozHnJOdGcBxMJzU/IyqqhP2JQJigWczLeVWt6fDC2UUM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/PV: avoid double stack reset during schedule tail handling
Message-Id: <E1kpZ91-00046X-4q@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 15:55:15 +0000

commit 2c2c941686d2aedac0f09b6546c844c391c0f7e8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:42:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:42:50 2020 +0100

    x86/PV: avoid double stack reset during schedule tail handling
    
    Invoking check_wakeup_from_wait() from assembly allows the new
    continue_pv_domain() to replace the prior continue_nonidle_domain() as
    the tail hook, eliminating an extra reset_stack_and_jump().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/pv/domain.c        | 9 ++-------
 xen/arch/x86/x86_64/entry.S     | 5 ++++-
 xen/include/asm-x86/asm_defns.h | 1 -
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 1a607f856e..23d6009143 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,12 +110,6 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(void)
-{
-    check_wakeup_from_wait();
-    reset_stack_and_jump(ret_from_intr);
-}
-
 static int setup_compat_l4(struct vcpu *v)
 {
     struct page_info *pg;
@@ -341,13 +335,14 @@ void pv_domain_destroy(struct domain *d)
     FREE_XENHEAP_PAGE(d->arch.pv.gdt_ldt_l1tab);
 }
 
+void noreturn continue_pv_domain(void);
 
 int pv_domain_initialise(struct domain *d)
 {
     static const struct arch_csw pv_csw = {
         .from = paravirt_ctxt_switch_from,
         .to   = paravirt_ctxt_switch_to,
-        .tail = continue_nonidle_domain,
+        .tail = continue_pv_domain,
     };
     int rc = -ENOMEM;
 
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 000eb9722b..526c388458 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -557,8 +557,10 @@ ENTRY(dom_crash_sync_extable)
         .text
 
 /* No special register assumptions. */
-ENTRY(ret_from_intr)
 #ifdef CONFIG_PV
+ENTRY(continue_pv_domain)
+        call  check_wakeup_from_wait
+ret_from_intr:
         GET_CURRENT(bx)
         testb $3, UREGS_cs(%rsp)
         jz    restore_all_xen
@@ -567,6 +569,7 @@ ENTRY(ret_from_intr)
         je    test_all_events
         jmp   compat_test_all_events
 #else
+ret_from_intr:
         ASSERT_CONTEXT_IS_XEN
         jmp   restore_all_xen
 #endif
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index b42a19b654..774a294d15 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -23,7 +23,6 @@ asm ( "\t.equ CONFIG_INDIRECT_THUNK, "
 #include <asm/indirect_thunk_asm.h>
 
 #ifndef __ASSEMBLY__
-void ret_from_intr(void);
 
 /*
  * This output constraint should be used for any inline asm which has a "call"
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 15:55:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 15:55:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55318.96399 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ9C-0001LO-Qh; Wed, 16 Dec 2020 15:55:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55318.96399; Wed, 16 Dec 2020 15:55:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ9C-0001LF-NI; Wed, 16 Dec 2020 15:55:26 +0000
Received: by outflank-mailman (input) for mailman id 55318;
 Wed, 16 Dec 2020 15:55:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9B-0001L8-Bp
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9B-00022P-9U
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9B-00047D-8H
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=k5QSv4IxJWXz3FzZj+f9Iygako6McBnyPximAOdgJe0=; b=DkCF1z98DO2oGRcHdFa/KfemiK
	yP9r2Qw95ithBV8ciaOQYJYmf4IlgVeOhh4mxo7anyTt9Ly+ghK/wle0jG0ypSqe4cCmhN/fPDWkE
	i/YFts18QgtzIDJWpbPZeVmrMPs5QfdfI9rOHdTc56goUH0+CfXFFKDv1FOqdMlUfzg8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] livepatch: adjust a stale comment
Message-Id: <E1kpZ9B-00047D-8H@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 15:55:25 +0000

commit 7dcaffce645bde8b59e127df640b769885c2ffe4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:43:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:43:32 2020 +0100

    livepatch: adjust a stale comment
    
    As of 005de45c887e ("xen: do live patching only from main idle loop")
    the comment ahead of livepatch_do_action() has been stale.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 xen/common/livepatch.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 81ceafce98..7118551b27 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1392,8 +1392,8 @@ static inline bool was_action_consistent(const struct payload *data, livepatch_f
 }
 
 /*
- * This function is executed having all other CPUs with no deep stack (we may
- * have cpu_idle on it) and IRQs disabled.
+ * This function is executed having all other CPUs with no deep stack (when
+ * idle) and IRQs disabled.
  */
 static void livepatch_do_action(void)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 15:55:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 15:55:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55319.96403 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ9M-0001Mp-Rn; Wed, 16 Dec 2020 15:55:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55319.96403; Wed, 16 Dec 2020 15:55:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpZ9M-0001Mh-Os; Wed, 16 Dec 2020 15:55:36 +0000
Received: by outflank-mailman (input) for mailman id 55319;
 Wed, 16 Dec 2020 15:55:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9L-0001MV-F4
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9L-00022b-DT
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpZ9L-00047p-Bg
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 15:55:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=iMj5d4/guRCvCP09aYJZMXcbCLMX3O9rKNJORkDuzkA=; b=4s80GigGUNLn9YIAasAWS6rdMq
	qU++p+cnY9gOuQDxBYOqPNVYdYv4EgS8aU6JZg4i7qp/pRY4VqUojBEOEKHXy52feCKMQ5blLP2KZ
	QgzAuTs49Ch8Wfo8w95spqA/uiWRH46tMQ5xhPbRkTSSFNyGIgDDBRRGlLbS8NLcvhvA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/p2m: set_shared_p2m_entry() is MEM_SHARING-only
Message-Id: <E1kpZ9L-00047p-Bg@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 15:55:35 +0000

commit 5a324e1c39b6b78496dc73c222c9874302c2423c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:44:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:44:18 2020 +0100

    x86/p2m: set_shared_p2m_entry() is MEM_SHARING-only
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Tamas K Lengyel <tamas@tklengyel.com>
---
 xen/arch/x86/mm/p2m.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index db6cc2202d..cd0812db18 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1466,6 +1466,8 @@ int clear_identity_p2m_entry(struct domain *d, unsigned long gfn_l)
     return ret;
 }
 
+#ifdef CONFIG_MEM_SHARING
+
 /* Returns: 0 for success, -errno for failure */
 int set_shared_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn)
 {
@@ -1504,7 +1506,10 @@ int set_shared_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn)
     return rc;
 }
 
+#endif /* CONFIG_MEM_SHARING */
+
 #ifdef CONFIG_HVM
+
 static struct p2m_domain *
 p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Wed Dec 16 18:11:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 16 Dec 2020 18:11:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55558.96698 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpbGT-0001IR-Vk; Wed, 16 Dec 2020 18:11:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55558.96698; Wed, 16 Dec 2020 18:11:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpbGT-0001IJ-SP; Wed, 16 Dec 2020 18:11:05 +0000
Received: by outflank-mailman (input) for mailman id 55558;
 Wed, 16 Dec 2020 18:11:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpbGS-0001IC-M3
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 18:11:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpbGS-00052H-Kf
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 18:11:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpbGS-0005sV-JN
 for xen-changelog@lists.xenproject.org; Wed, 16 Dec 2020 18:11:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tbHveHhWXE5b5AteybkUanWpmnIL/y8rpH7DA8ll6j8=; b=zevm3SRbAOUeT5xxxmgM7TE833
	Kjj1cqlddjq/AophMSuyn3ZWSRcsuOGWclN2vwng/VfZn4GN3zsypP0awMUzP8V4hnKPz23DeYF/0
	0KVqAxlWFkIIzoV3Y8DZMNOfcNLNqEL5yhow1WSKWOkdQ/2UfCkoWxR08hvGFtyR6g1M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] Revert patches that break libxl API
Message-Id: <E1kpbGS-0005sV-JN@xenbits.xenproject.org>
Date: Wed, 16 Dec 2020 18:11:04 +0000

commit ac6a0af3870ba0f7ffb16af3e41827b0a53f88b0
Author:     Wei Liu <wl@xen.org>
AuthorDate: Wed Dec 16 17:48:04 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Wed Dec 16 18:03:26 2020 +0000

    Revert patches that break libxl API
    
    This patch reverts eight patches from staging.
    
    The offending patch is the one that introduced libxl_pci_bdf (last one
    in the list). The rest depend on that patch so they are also reverted.
    
    8bf0fab14256 "libxl / libxlu: support 'xl pci-attach/detach' by name"
    e1141654c374 "docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING"
    93c16ae47baf "xl: support naming of assignable devices"
    5ab684cb3e4d "libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ..."
    66c2fbc6e82b "libxl: convert internal functions in libxl_pci.c..."
    f73c5dd56d78 "docs/man: modify xl(1) in preparation for naming of assignable devices"
    96ed6ff29741 "libxlu: introduce xlu_pci_parse_spec_string()"
    929f23114061 "libxl: introduce 'libxl_pci_bdf' in the idl..."
    
    Signed-off-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod  |  25 +-
 docs/man/xl.1.pod.in                 |  19 +-
 tools/golang/xenlight/helpers.gen.go |  77 ++----
 tools/golang/xenlight/types.gen.go   |   8 +-
 tools/include/libxl.h                |  48 +---
 tools/include/libxlutil.h            |   8 +-
 tools/libs/light/libxl_dm.c          |   8 +-
 tools/libs/light/libxl_internal.h    |   3 +-
 tools/libs/light/libxl_pci.c         | 501 +++++++++++------------------------
 tools/libs/light/libxl_types.idl     |  17 +-
 tools/libs/util/libxlu_pci.c         | 359 ++++++++++++-------------
 tools/xl/xl_cmdtable.c               |  16 +-
 tools/xl/xl_parse.c                  |   4 +-
 tools/xl/xl_pci.c                    | 133 ++++------
 tools/xl/xl_sxp.c                    |   4 +-
 15 files changed, 431 insertions(+), 799 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index db3360307c..4dd73bc498 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -51,7 +51,7 @@ is not specified, or if it is specified with an empty value (whether
 positionally or explicitly).
 
 B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
-B<bdf> or B<name> will be ignored.
+B<bdf> will be ignored.
 
 =head1 Positional Parameters
 
@@ -70,11 +70,7 @@ B<*> to indicate all functions of a multi-function device.
 
 =item Default Value
 
-None. This parameter is mandatory in its positional form. As a non-positional
-parameter it is also mandatory unless a B<name> parameter is present, in
-which case B<bdf> must not be present since the B<name> will be used to find
-the B<bdf> in the list of assignable devices. See L<xl(1)> for more information
-on naming assignable devices.
+None. This parameter is mandatory as it identifies the device.
 
 =back
 
@@ -198,21 +194,4 @@ B<NOTE>: This overrides the global B<rdm> option.
 
 =back
 
-=item B<name>=I<STRING>
-
-=over 4
-
-=item Description
-
-This is the name given when the B<BDF> was made assignable. See L<xl(1)> for
-more information on naming assignable devices.
-
-=item Default Value
-
-None. This parameter must not be present if a B<bdf> parameter is present.
-If a B<bdf> parameter is not present then B<name> is mandatory as it is
-required to look up the B<BDF> in the list of assignable devices.
-
-=back
-
 =back
diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index f4779d8fd6..af31d2b572 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1595,23 +1595,19 @@ List virtual network interfaces for a domain.
 
 =over 4
 
-=item B<pci-assignable-list> [I<-n>]
+=item B<pci-assignable-list>
 
 List all the B<BDF> of assignable PCI devices. See
-L<xl-pci-configuration(5)> for more information. If the -n option is
-specified then any name supplied when the device was made assignable
-will also be displayed.
+L<xl-pci-configuration(5)> for more information.
 
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
-=item B<pci-assignable-add> [I<-n NAME>] I<BDF>
+=item B<pci-assignable-add> I<BDF>
 
 Make the device at B<BDF> assignable to guests. See
-L<xl-pci-configuration(5)> for more information. If the -n option is
-supplied then the assignable device entry will the named with the
-given B<NAME>.
+L<xl-pci-configuration(5)> for more information.
 
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
@@ -1626,11 +1622,10 @@ not to do this on a device critical to domain 0's operation, such as
 storage controllers, network interfaces, or GPUs that are currently
 being used.
 
-=item B<pci-assignable-remove> [I<-r>] I<BDF>|I<NAME>
+=item B<pci-assignable-remove> [I<-r>] I<BDF>
 
-Make a device non-assignable to guests. The device may be identified
-either by its B<BDF> or the B<NAME> supplied when the device was made
-assignable. See L<xl-pci-configuration(5)> for more information.
+Make the device at B<BDF> not assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
 
 This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index b7230f693c..c8605994e7 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1999,41 +1999,6 @@ xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)}
  return nil
  }
 
-// NewPciBdf returns an instance of PciBdf initialized with defaults.
-func NewPciBdf() (*PciBdf, error) {
-var (
-x PciBdf
-xc C.libxl_pci_bdf)
-
-C.libxl_pci_bdf_init(&xc)
-defer C.libxl_pci_bdf_dispose(&xc)
-
-if err := x.fromC(&xc); err != nil {
-return nil, err }
-
-return &x, nil}
-
-func (x *PciBdf) fromC(xc *C.libxl_pci_bdf) error {
- x.Func = byte(xc._func)
-x.Dev = byte(xc.dev)
-x.Bus = byte(xc.bus)
-x.Domain = int(xc.domain)
-
- return nil}
-
-func (x *PciBdf) toC(xc *C.libxl_pci_bdf) (err error){defer func(){
-if err != nil{
-C.libxl_pci_bdf_dispose(xc)}
-}()
-
-xc._func = C.uint8_t(x.Func)
-xc.dev = C.uint8_t(x.Dev)
-xc.bus = C.uint8_t(x.Bus)
-xc.domain = C.int(x.Domain)
-
- return nil
- }
-
 // NewDevicePci returns an instance of DevicePci initialized with defaults.
 func NewDevicePci() (*DevicePci, error) {
 var (
@@ -2049,9 +2014,10 @@ return nil, err }
 return &x, nil}
 
 func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
- if err := x.Bdf.fromC(&xc.bdf);err != nil {
-return fmt.Errorf("converting field Bdf: %v", err)
-}
+ x.Func = byte(xc._func)
+x.Dev = byte(xc.dev)
+x.Bus = byte(xc.bus)
+x.Domain = int(xc.domain)
 x.Vdevfn = uint32(xc.vdevfn)
 x.VfuncMask = uint32(xc.vfunc_mask)
 x.Msitranslate = bool(xc.msitranslate)
@@ -2067,9 +2033,10 @@ if err != nil{
 C.libxl_device_pci_dispose(xc)}
 }()
 
-if err := x.Bdf.toC(&xc.bdf); err != nil {
-return fmt.Errorf("converting field Bdf: %v", err)
-}
+xc._func = C.uint8_t(x.Func)
+xc.dev = C.uint8_t(x.Dev)
+xc.bus = C.uint8_t(x.Bus)
+xc.domain = C.int(x.Domain)
 xc.vdevfn = C.uint32_t(x.Vdevfn)
 xc.vfunc_mask = C.uint32_t(x.VfuncMask)
 xc.msitranslate = C.bool(x.Msitranslate)
@@ -2799,13 +2766,13 @@ if err := x.Nics[i].fromC(&v); err != nil {
 return fmt.Errorf("converting field Nics: %v", err) }
 }
 }
-x.Pcis = nil
-if n := int(xc.num_pcis); n > 0 {
-cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:n:n]
-x.Pcis = make([]DevicePci, n)
-for i, v := range cPcis {
-if err := x.Pcis[i].fromC(&v); err != nil {
-return fmt.Errorf("converting field Pcis: %v", err) }
+x.Pcidevs = nil
+if n := int(xc.num_pcidevs); n > 0 {
+cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n]
+x.Pcidevs = make([]DevicePci, n)
+for i, v := range cPcidevs {
+if err := x.Pcidevs[i].fromC(&v); err != nil {
+return fmt.Errorf("converting field Pcidevs: %v", err) }
 }
 }
 x.Rdms = nil
@@ -2955,13 +2922,13 @@ return fmt.Errorf("converting field Nics: %v", err)
 }
 }
 }
-if numPcis := len(x.Pcis); numPcis > 0 {
-xc.pcis = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcis)*C.sizeof_libxl_device_pci))
-xc.num_pcis = C.int(numPcis)
-cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:numPcis:numPcis]
-for i,v := range x.Pcis {
-if err := v.toC(&cPcis[i]); err != nil {
-return fmt.Errorf("converting field Pcis: %v", err)
+if numPcidevs := len(x.Pcidevs); numPcidevs > 0 {
+xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs)*C.sizeof_libxl_device_pci))
+xc.num_pcidevs = C.int(numPcidevs)
+cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
+for i,v := range x.Pcidevs {
+if err := v.toC(&cPcidevs[i]); err != nil {
+return fmt.Errorf("converting field Pcidevs: %v", err)
 }
 }
 }
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index bc62ae8ce9..b4c5df0f2c 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -707,15 +707,11 @@ ColoCheckpointHost string
 ColoCheckpointPort string
 }
 
-type PciBdf struct {
+type DevicePci struct {
 Func byte
 Dev byte
 Bus byte
 Domain int
-}
-
-type DevicePci struct {
-Bdf PciBdf
 Vdevfn uint32
 VfuncMask uint32
 Msitranslate bool
@@ -900,7 +896,7 @@ CInfo DomainCreateInfo
 BInfo DomainBuildInfo
 Disks []DeviceDisk
 Nics []DeviceNic
-Pcis []DevicePci
+Pcidevs []DevicePci
 Rdms []DeviceRdm
 Dtdevs []DeviceDtdev
 Vfbs []DeviceVfb
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 90a7aa9b73..3433c950f9 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -463,25 +463,6 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
 
-/*
- * LIBXL_HAVE_PCI_BDF indicates that the 'libxl_pci_bdf' type is defined
- * is embedded in the 'libxl_device_pci' type.
- */
-#define LIBXL_HAVE_PCI_BDF 1
-
-/*
- * LIBXL_HAVE_PCI_ASSIGNABLE_BDF indicates that the
- * libxl_pci_bdf_assignable_add/remove/list/list_free() functions all
- * exist.
- */
-#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
-
-/*
- * LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of
- * libxl_device_pci is defined.
- */
-#define LIBXL_HAVE_DEVICE_PCI_NAME 1
-
 /*
  * libxl ABI compatibility
  *
@@ -2370,9 +2351,9 @@ int libxl_device_events_handler(libxl_ctx *ctx,
                                 LIBXL_EXTERNAL_CALLERS_ONLY;
 
 /*
- * Functions related to making PCI devices with the specified BDF
- * assignable -- that is, bound to the pciback driver, ready to be given to
- * a guest via libxl_pci_device_add.
+ * Functions related to making devices assignable -- that is, bound to
+ * the pciback driver, ready to be given to a guest via
+ * libxl_pci_device_add.
  *
  * - ..._add() will unbind the device from its current driver (if
  * already bound) and re-bind it to pciback; at that point it will be
@@ -2384,31 +2365,16 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * rebind is non-zero, attempt to assign it back to the driver
  * from whence it came.
  *
- * - ..._list() will return a list of the PCI BDFs available to be
+ * - ..._list() will return a list of the PCI devices available to be
  * assigned.
  *
  * add and remove are idempotent: if the device in question is already
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                 const char *name, int rebind);
-int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                    int rebind);
-libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num);
-void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num);
-libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
-                                                 const char *name);
-char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
-                                        libxl_pci_bdf *pcibdf);
-
-/* Compatibility functions - Use libxl_pci_bdf_assignable_* instead */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind);
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
-                                                   int *num);
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
 void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
diff --git a/tools/include/libxlutil.h b/tools/include/libxlutil.h
index cdd6aab4f8..92e35c5462 100644
--- a/tools/include/libxlutil.h
+++ b/tools/include/libxlutil.h
@@ -108,16 +108,10 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs,
    * resulting disk struct is used with libxl.
    */
 
-/*
- * PCI BDF
- */
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str);
-
 /*
  * PCI specification parsing
  */
-int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pci,
-                              const char *str);
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str);
 
 /*
  * RDM parsing
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 1b951b0920..3da83259c0 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -472,10 +472,10 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     for (i = 0; i < d_config->num_pcidevs; i++) {
         unsigned int n, nr_entries;
 
-        seg = d_config->pcidevs[i].bdf.domain;
-        bus = d_config->pcidevs[i].bdf.bus;
-        devfn = PCI_DEVFN(d_config->pcidevs[i].bdf.dev,
-                          d_config->pcidevs[i].bdf.func);
+        seg = d_config->pcidevs[i].domain;
+        bus = d_config->pcidevs[i].bus;
+        devfn = PCI_DEVFN(d_config->pcidevs[i].dev,
+                          d_config->pcidevs[i].func);
         nr_entries = 0;
         rc = libxl__xc_device_get_rdm(gc, 0,
                                       seg, bus, devfn, &nr_entries, &xrdm);
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index 6be7b12e4c..c79523ba92 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,11 +4746,10 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_BDF(a, b) ((a)->domain == (b)->domain && \
+#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
                            (a)->bus == (b)->bus &&       \
                            (a)->dev == (b)->dev &&       \
                            (a)->func == (b)->func)
-#define COMPARE_PCI(a, b) COMPARE_BDF(&((a)->bdf), &((b)->bdf))
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 5d83db2a59..74c2196ae3 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,33 +25,26 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pci_encode_bdf(libxl_pci_bdf *pcibdf)
+static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pcibdf->domain << 16;
-    value |= (pcibdf->bus & 0xff) << 8;
-    value |= (pcibdf->dev & 0x1f) << 3;
-    value |= (pcibdf->func & 0x7);
+    value = pci->domain << 16;
+    value |= (pci->bus & 0xff) << 8;
+    value |= (pci->dev & 0x1f) << 3;
+    value |= (pci->func & 0x7);
 
     return value;
 }
 
-static void pcibdf_struct_fill(libxl_pci_bdf *pcibdf, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func)
-{
-    pcibdf->domain = domain;
-    pcibdf->bus = bus;
-    pcibdf->dev = dev;
-    pcibdf->func = func;
-}
-
 static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pcibdf_struct_fill(&pci->bdf, domain, bus, dev, func);
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
     pci->vdevfn = vdevfn;
 }
 
@@ -60,14 +53,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             int num,
                                             const libxl_device_pci *pci)
 {
-    if (pci->name) {
-        flexarray_append(back, GCSPRINTF("name-%d", num));
-        flexarray_append(back, GCSPRINTF("%s", pci->name));
-    }
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     if (pci->vdevfn)
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
@@ -261,8 +250,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pci->bdf.domain && bus == pci->bdf.bus &&
-            pci->bdf.dev == dev && pci->bdf.func == func) {
+        if (domain == pci->domain && bus == pci->bus &&
+            pci->dev == dev && pci->func == func) {
             break;
         }
     }
@@ -288,7 +277,6 @@ retry_transaction:
 
 retry_transaction2:
     t = xs_transaction_start(ctx->xsh);
-    xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i));
@@ -327,12 +315,6 @@ retry_transaction2:
             xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
-        tmppath = GCSPRINTF("%s/name-%d", be_path, j);
-        tmp = libxl__xs_read(gc, t, tmppath);
-        if (tmp) {
-            xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp));
-            xs_rm(ctx->xsh, t, tmppath);
-        }
     }
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
@@ -368,8 +350,8 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num,
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
-static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
-                           libxl_pci_bdf *pcibdf)
+static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
+                           libxl_device_pci *pci)
 {
     int rc, fd;
     char *buf;
@@ -380,8 +362,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pcibdf->domain, pcibdf->bus,
-                    pcibdf->dev, pcibdf->func);
+    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
+                    pci->dev, pci->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -396,22 +378,22 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
 
 #define PCI_INFO_PATH "/libxl/pci"
 
-static char *pci_info_xs_path(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node)
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
+                  pci->domain, pci->bus, pci->dev, pci->func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+                  pci->domain, pci->bus, pci->dev, pci->func);
 }
 
 
-static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node, const char *val)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
     int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
 
     if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
@@ -419,28 +401,28 @@ static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
     return rc;
 }
 
-static char *pci_info_xs_read(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
 
     return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
                                const char *node)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
     xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
-libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_pci_bdf *pcibdfs = NULL, *new;
+    libxl_device_pci *pcis = NULL, *new;
     struct dirent *de;
     DIR *dir;
 
@@ -461,15 +443,15 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        new = realloc(pcibdfs, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcibdfs = new;
-        new = pcibdfs + *num;
+        pcis = new;
+        new = pcis + *num;
 
-        libxl_pci_bdf_init(new);
-        pcibdf_struct_fill(new, dom, bus, dev, func);
+        libxl_device_pci_init(new);
+        pci_struct_fill(new, dom, bus, dev, func, 0);
 
         if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
             continue;
@@ -480,32 +462,32 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
     closedir(dir);
 out:
     GC_FREE;
-    return pcibdfs;
+    return pcis;
 }
 
-void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num)
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
 {
     int i;
 
     for (i = 0; i < num; i++)
-        libxl_pci_bdf_dispose(&list[i]);
+        libxl_device_pci_dispose(&list[i]);
 
     free(list);
 }
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pcibdf->domain,
-                           pcibdf->bus,
-                           pcibdf->dev,
-                           pcibdf->func);
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -519,7 +501,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pcibdf) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -535,7 +517,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -543,7 +525,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -551,7 +533,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
@@ -562,7 +544,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -570,7 +552,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -578,7 +560,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
@@ -589,14 +571,14 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                     pci->domain, pci->bus, pci->dev, pci->func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -605,7 +587,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
     }
 
@@ -657,8 +639,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+/* Scan through /sys/.../pciback/slots looking for pci's BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
 {
     FILE *f;
     int rc = 0;
@@ -672,10 +654,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pcibdf->domain
-            && bus == pcibdf->bus
-            && dev == pcibdf->dev
-            && func == pcibdf->func) {
+        if (dom == pci->domain
+            && bus == pci->bus
+            && dev == pci->dev
+            && func == pci->func) {
             rc = 1;
             goto out;
         }
@@ -685,7 +667,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
 {
     char * spath;
     int rc;
@@ -701,8 +683,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pcibdf->domain, pcibdf->bus,
-                      pcibdf->dev, pcibdf->func);
+                      pci->domain, pci->bus,
+                      pci->dev, pci->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -713,40 +695,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
 {
     int rc;
 
-    if ( (rc = pciback_dev_has_slot(gc, pcibdf)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pcibdf) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcibdf) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pcibdf, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pcibdf) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pcibdf) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -754,10 +736,9 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     return 0;
 }
 
-static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
-                                         libxl_pci_bdf *pcibdf,
-                                         const char *name,
-                                         int rebind)
+static int libxl__device_pci_assignable_add(libxl__gc *gc,
+                                            libxl_device_pci *pci,
+                                            int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     unsigned dom, bus, dev, func;
@@ -765,28 +746,11 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     int rc;
     struct stat st;
 
-    /* Sanitise any name that was passed */
-    if (name) {
-        unsigned int i, n = strlen(name);
-
-        if (n > 64) { /* Reasonable upper bound on name length */
-            LOG(ERROR, "Name too long");
-            return ERROR_FAIL;
-        }
-
-        for (i = 0; i < n; i++) {
-            if (!isgraph(name[i])) {
-                LOG(ERROR, "Names may only include printable characters");
-                return ERROR_FAIL;
-            }
-        }
-    }
-
     /* Local copy for convenience */
-    dom = pcibdf->domain;
-    bus = pcibdf->bus;
-    dev = pcibdf->dev;
-    func = pcibdf->func;
+    dom = pci->domain;
+    bus = pci->bus;
+    dev = pci->dev;
+    func = pci->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -796,17 +760,17 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pcibdf);
+    rc = pciback_dev_is_assigned(gc, pci);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
     if ( rc ) {
         LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func);
-        goto name;
+        goto quarantine;
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pcibdf, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -815,9 +779,9 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_info_xs_write(gc, pcibdf, "driver_path", driver_path);
+            pci_info_xs_write(gc, pci, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_info_xs_read(gc, pcibdf, "driver_path")) != NULL ) {
+                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -825,26 +789,21 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_info_xs_remove(gc, pcibdf, "driver_path");
+        pci_info_xs_remove(gc, pci, "driver_path");
     }
 
-    if ( pciback_dev_assign(gc, pcibdf) ) {
+    if ( pciback_dev_assign(gc, pci) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
 
-name:
-    if (name)
-        pci_info_xs_write(gc, pcibdf, "name", name);
-    else
-        pci_info_xs_remove(gc, pcibdf, "name");
-
+quarantine:
     /*
      * DOMID_IO is just a sentinel domain, without any actual mappings,
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -854,33 +813,33 @@ name:
     return 0;
 }
 
-static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
-                                            libxl_pci_bdf *pcibdf,
-                                            int rebind)
+static int libxl__device_pci_assignable_remove(libxl__gc *gc,
+                                               libxl_device_pci *pci,
+                                               int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc;
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcibdf->domain,
-            pcibdf->bus, pcibdf->dev, pcibdf->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
+            pci->dev, pci->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc = pciback_dev_is_assigned(gc, pcibdf)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pcibdf);
+        pciback_dev_unassign(gc, pci);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_info_xs_read(gc, pcibdf, "driver_path");
+    driver_path = pci_info_xs_read(gc, pci, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -888,12 +847,12 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pcibdf) < 0 ) {
+                                 pci) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_info_xs_remove(gc, pcibdf, "driver_path");
+            pci_info_xs_remove(gc, pci, "driver_path");
         }
     } else {
         if ( rebind ) {
@@ -902,87 +861,34 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
         }
     }
 
-    pci_info_xs_remove(gc, pcibdf, "name");
-
     return 0;
 }
 
-int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                 const char *name, int rebind)
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_add(gc, pcibdf, name, rebind);
+    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                    int rebind)
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_remove(gc, pcibdf, rebind);
+    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
-libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
-                                                 const char *name)
-{
-    GC_INIT(ctx);
-    char **bdfs;
-    libxl_pci_bdf *pcibdf = NULL;
-    unsigned int i, n;
-
-    bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n);
-    if (!n)
-        goto out;
-
-    pcibdf = calloc(1, sizeof(*pcibdf));
-    if (!pcibdf)
-        goto out;
-
-    for (i = 0; i < n; i++) {
-        unsigned dom, bus, dev, func;
-        const char *tmp;
-
-        if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4)
-            continue;
-
-        pcibdf_struct_fill(pcibdf, dom, bus, dev, func);
-
-        tmp = pci_info_xs_read(gc, pcibdf, "name");
-        if (tmp && !strcmp(tmp, name))
-            goto out;
-    }
-
-    free(pcibdf);
-    pcibdf = NULL;
-
-out:
-    GC_FREE;
-    return pcibdf;
-}
-
-char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
-                                        libxl_pci_bdf *pcibdf)
-{
-    GC_INIT(ctx);
-    char *name = NULL, *tmp = pci_info_xs_read(gc, pcibdf, "name");
-
-    if (tmp)
-        name = strdup(tmp);
-
-    GC_FREE;
-    return name;
-}
-
 /*
  * This function checks that all functions of a device are bound to pciback
  * driver. It also initialises a bit-mask of which function numbers are present
@@ -1008,11 +914,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigne
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pci->bdf.domain != dom )
+        if ( pci->domain != dom )
             continue;
-        if ( pci->bdf.bus != bus )
+        if ( pci->bus != bus )
             continue;
-        if ( pci->bdf.dev != dev )
+        if ( pci->dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -1061,13 +967,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
     if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pci->bdf.domain, pci->bdf.bus, pci->bdf.dev,
-                         pci->bdf.func, pci->vdevfn, pci->msitranslate,
+                         pci->domain, pci->bus, pci->dev,
+                         pci->func, pci->vdevfn, pci->msitranslate,
                          pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pci->bdf.domain,  pci->bdf.bus, pci->bdf.dev,
-                         pci->bdf.func, pci->msitranslate, pci->power_mgmt);
+                         pci->domain,  pci->bus, pci->dev,
+                         pci->func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1226,10 +1132,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           pci->bus, pci->dev, pci->func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pci->bdf.domain,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           "%04x:%02x:%02x.%01x", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
                                PCI_SLOT(pci->vdevfn),
@@ -1317,7 +1223,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                         pci->bus, pci->dev, pci->func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1408,8 +1314,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1449,8 +1355,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
-                                pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                                pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1479,7 +1385,7 @@ static void pci_add_dm_done(libxl__egc *egc,
     /* Don't restrict writes to the PCI config space from this VM */
     if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             &pci->bdf) < 0 ) {
+                             pci) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1495,8 +1401,7 @@ out_no_irq:
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(&pci->bdf),
-                             flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1575,21 +1480,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
+static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
-    libxl_pci_bdf *pcibdfs;
-    int num, i;
-
-    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
-
-    for (i = 0; i < num; i++) {
-        if (COMPARE_BDF(pcibdf, &pcibdfs[i]))
-            break;
-    }
+    libxl_device_pci *pcis;
+    int num;
+    bool assignable;
 
-    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    assignable = is_pci_in_array(pcis, num, pci);
+    libxl_device_pci_assignable_list_free(pcis, num);
 
-    return i < num;
+    return assignable;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1621,30 +1522,12 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
-    if (pci->name) {
-        libxl_pci_bdf *pcibdf =
-            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
-
-        if (!pcibdf) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
-             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
-
-        libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf);
-        libxl_pci_bdf_dispose(pcibdf);
-        free(pcibdf);
-    }
-
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid,
-                                   pci_encode_bdf(&pci->bdf));
+        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                 pci->domain, pci->bus, pci->dev, pci->func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
@@ -1654,23 +1537,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
-        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, NULL, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
+        rc = libxl__device_pci_assignable_add(gc, pci, 1);
         if ( rc )
             goto out;
     }
 
-    if (!is_bdf_assignable(ctx, &pci->bdf)) {
+    if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         rc = ERROR_FAIL;
         goto out;
     }
 
-    rc = pci_info_xs_write(gc, &pci->bdf, "domid", GCSPRINTF("%u", domid));
+    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
-    libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
@@ -1751,13 +1634,13 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
         pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pci->bdf.func);
+        pfunc_mask = (1 << pci->func);
     }
 
     for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->bdf.func = i;
+                pci->func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 /* if not passing through multiple devices in a block make
@@ -1786,20 +1669,12 @@ static void device_pci_add_done(libxl__egc *egc,
     libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
-        if (pci->name) {
-            LOGD(ERROR, domid,
-                 "libxl__device_pci_add failed for "
-                 "PCI device '%s' (rc %d)",
-                 pci->name,
-                 rc);
-        } else {
-            LOGD(ERROR, domid,
-                 "libxl__device_pci_add failed for "
-                 "PCI device %x:%x:%x.%x (rc %d)",
-                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
-                 rc);
-        }
-        pci_info_xs_remove(gc, &pci->bdf, "domid");
+        LOGD(ERROR, domid,
+             "libxl__device_pci_add  failed for "
+             "PCI device %x:%x:%x.%x (rc %d)",
+             pci->domain, pci->bus, pci->dev, pci->func,
+             rc);
+        pci_info_xs_remove(gc, pci, "domid");
     }
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -1866,8 +1741,8 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->bdf.domain,
-                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
+                     pci->bus, pci->dev, pci->func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
@@ -1981,8 +1856,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
-                                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                                     pci->bus, pci->dev, pci->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -2017,8 +1892,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
-                               pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                               pci->bus, pci->dev, pci->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -2082,7 +1957,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           pci->bus, pci->dev, pci->func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2151,7 +2026,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                         pci->bus, pci->dev, pci->func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2202,7 +2077,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2235,12 +2110,11 @@ static void pci_remove_detached(libxl__egc *egc,
 
     /* don't do multiple resets while some functions are still passed through */
     if ((pci->vdevfn & 0x7) == 0) {
-        libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid,
-                                pci_encode_bdf(&pci->bdf));
+        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
@@ -2315,23 +2189,6 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
-    if (pci->name) {
-        libxl_pci_bdf *pcibdf =
-            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
-
-        if (!pcibdf) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
-             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
-
-        libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf);
-        libxl_pci_bdf_dispose(pcibdf);
-        free(pcibdf);
-    }
-
     prs->orig_vdev = pci->vdevfn & ~7U;
 
     if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
@@ -2341,7 +2198,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
         }
         pci->vfunc_mask &= prs->pfunc_mask;
     } else {
-        prs->pfunc_mask = (1 << pci->bdf.func);
+        prs->pfunc_mask = (1 << pci->func);
     }
 
     rc = 0;
@@ -2369,7 +2226,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->bdf.func = i;
+                pci->func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 pci->vdevfn = orig_vdev;
@@ -2386,7 +2243,7 @@ out:
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
 
-    if (!rc) pci_info_xs_remove(gc, &pci->bdf, "domid");
+    if (!rc) pci_info_xs_remove(gc, pci, "domid");
 
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -2466,10 +2323,6 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
 
-    s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr));
-    if (s)
-        pci->name = strdup(s);
-
     return 0;
 }
 
@@ -2582,48 +2435,6 @@ DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind)
-{
-    return libxl_pci_bdf_assignable_add(ctx, &pci->bdf, NULL, rebind);
-}
-
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind)
-{
-    return libxl_pci_bdf_assignable_remove(ctx, &pci->bdf, rebind);
-}
-
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
-                                                   int *num)
-{
-    libxl_pci_bdf *pcibdfs = libxl_pci_bdf_assignable_list(ctx, num);
-    libxl_device_pci *pcis;
-    unsigned int i;
-
-    if (!pcibdfs)
-        return NULL;
-
-    pcis = calloc(*num, sizeof(*pcis));
-    if (!pcis) {
-        libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
-        return NULL;
-    }
-
-    for (i = 0; i < *num; i++) {
-        libxl_device_pci_init(&pcis[i]);
-        libxl_pci_bdf_copy(ctx, &pcis[i].bdf, &pcibdfs[i]);
-    }
-
-    libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
-    return pcis;
-}
-
-void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
-{
-    libxl_device_pci_list_free(list, num);
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 32cc99beff..05324736b7 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -770,23 +770,18 @@ libxl_device_nic = Struct("device_nic", [
     ("colo_checkpoint_port", string)
     ])
 
-libxl_pci_bdf = Struct("pci_bdf", [
-    ("func", uint8),
-    ("dev", uint8),
-    ("bus", uint8),
-    ("domain", integer),
-    ])
-
 libxl_device_pci = Struct("device_pci", [
-    ("bdf", libxl_pci_bdf),
-    ("name", string),
-    ("vdevfn", uint32),
+    ("func",      uint8),
+    ("dev",       uint8),
+    ("bus",       uint8),
+    ("domain",    integer),
+    ("vdevfn",    uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
     ("power_mgmt", bool),
     ("permissive", bool),
     ("seize", bool),
-    ("rdm_policy", libxl_rdm_reserve_policy),
+    ("rdm_policy",      libxl_rdm_reserve_policy),
     ])
 
 libxl_device_rdm = Struct("device_rdm", [
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 543a1f80e9..1d38fffce3 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -1,7 +1,5 @@
 #define _GNU_SOURCE
 
-#include <ctype.h>
-
 #include "libxlu_internal.h"
 #include "libxlu_disk_l.h"
 #include "libxlu_disk_i.h"
@@ -11,218 +9,185 @@
 #define XLU__PCI_ERR(_c, _x, _a...) \
     if((_c) && (_c)->report) fprintf((_c)->report, _x, ##_a)
 
-static int parse_bdf(libxl_pci_bdf *bdfp, uint32_t *vfunc_maskp,
-                     const char *str, const char **endp)
+static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
 {
-    const char *ptr = str;
-    unsigned int colons = 0;
-    unsigned int domain, bus, dev, func;
-    int n;
-
-    /* Count occurrences of ':' to detrmine presence/absence of the 'domain' */
-    while (isxdigit(*ptr) || *ptr == ':') {
-        if (*ptr == ':')
-            colons++;
-        ptr++;
-    }
-
-    ptr = str;
-    switch (colons) {
-    case 1:
-        domain = 0;
-        if (sscanf(ptr, "%x:%x.%n", &bus, &dev, &n) != 2)
-            return ERROR_INVAL;
-        break;
-    case 2:
-        if (sscanf(ptr, "%x:%x:%x.%n", &domain, &bus, &dev, &n) != 3)
-            return ERROR_INVAL;
-        break;
-    default:
-        return ERROR_INVAL;
-    }
-
-    if (domain > 0xffff || bus > 0xff || dev > 0x1f)
-        return ERROR_INVAL;
-
-    ptr += n;
-    if (*ptr == '*') {
-        if (!vfunc_maskp)
-            return ERROR_INVAL;
-        *vfunc_maskp = LIBXL_PCI_FUNC_ALL;
-        func = 0;
-        ptr++;
-    } else {
-        if (sscanf(ptr, "%x%n", &func, &n) != 1)
-            return ERROR_INVAL;
-        if (func > 7)
-            return ERROR_INVAL;
-        if (vfunc_maskp)
-            *vfunc_maskp = 1;
-        ptr += n;
-    }
-
-    bdfp->domain = domain;
-    bdfp->bus = bus;
-    bdfp->dev = dev;
-    bdfp->func = func;
-
-    if (endp)
-        *endp = ptr;
-
+    unsigned long ret;
+    char *end;
+
+    ret = strtoul(str, &end, 16);
+    if ( end == str || *end != '\0' )
+        return -1;
+    if ( ret & ~mask )
+        return -1;
+    *val = (unsigned int)ret & mask;
     return 0;
 }
 
-static int parse_vslot(uint32_t *vdevfnp, const char *str, const char **endp)
+static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                           unsigned int bus, unsigned int dev,
+                           unsigned int func, unsigned int vdevfn)
 {
-    const char *ptr = str;
-    unsigned int val;
-    int n;
-
-    if (sscanf(ptr, "%x%n", &val, &n) != 1)
-        return ERROR_INVAL;
-
-    if (val > 0x1f)
-        return ERROR_INVAL;
-
-    ptr += n;
-
-    *vdevfnp = val << 3;
-
-    if (endp)
-        *endp = ptr;
-
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
     return 0;
 }
 
-static int parse_key_val(char **keyp, char**valp, const char *str,
-                         const char **endp)
+#define STATE_DOMAIN    0
+#define STATE_BUS       1
+#define STATE_DEV       2
+#define STATE_FUNC      3
+#define STATE_VSLOT     4
+#define STATE_OPTIONS_K 6
+#define STATE_OPTIONS_V 7
+#define STATE_TERMINAL  8
+#define STATE_TYPE      9
+#define STATE_RDM_STRATEGY      10
+#define STATE_RESERVE_POLICY    11
+#define INVALID         0xffffffff
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
 {
-    const char *ptr = str;
-    char *key, *val;
-
-    while (*ptr != '=' && *ptr != '\0')
-        ptr++;
+    unsigned state = STATE_DOMAIN;
+    unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
+    char *buf2, *tok, *ptr, *end, *optkey = NULL;
 
-    if (*ptr == '\0')
-        return ERROR_INVAL;
-
-    key = strndup(str, ptr - str);
-    if (!key)
-        return ERROR_NOMEM;
-
-    str = ++ptr; /* skip '=' */
-    while (*ptr != ',' && *ptr != '\0')
-        ptr++;
-
-    val = strndup(str, ptr - str);
-    if (!val) {
-        free(key);
+    if ( NULL == (buf2 = ptr = strdup(str)) )
         return ERROR_NOMEM;
-    }
-
-    if (*ptr == ',')
-        ptr++;
 
-    *keyp = key;
-    *valp = val;
-    *endp = ptr;
-
-    return 0;
-}
-
-static int parse_rdm_policy(XLU_Config *cfg, libxl_rdm_reserve_policy *policy,
-                            const char *str)
-{
-    int ret = libxl_rdm_reserve_policy_from_string(str, policy);
-
-    if (ret)
-        XLU__PCI_ERR(cfg, "Unknown RDM policy: %s", str);
-
-    return ret;
-}
-
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str)
-{
-    return parse_bdf(bdf, NULL, str, NULL);
-}
-
-int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
-                              const char *str)
-{
-    const char *ptr = str;
-    bool bdf_present = false;
-    bool name_present = false;
-    int ret;
-
-    /* Attempt to parse 'bdf' as positional parameter */
-    ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, ptr, &ptr);
-    if (!ret) {
-        bdf_present = true;
-
-        /* Check whether 'vslot' if present */
-        if (*ptr == '@') {
-            ret = parse_vslot(&pcidev->vdevfn, ++ptr, &ptr);
-            if (ret)
-                return ret;
+    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
+        switch(state) {
+        case STATE_DOMAIN:
+            if ( *ptr == ':' ) {
+                state = STATE_BUS;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dom, 0xffff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_BUS:
+            if ( *ptr == ':' ) {
+                state = STATE_DEV;
+                *ptr = '\0';
+                if ( hex_convert(tok, &bus, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }else if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( dom & ~0xff )
+                    goto parse_error;
+                bus = dom;
+                dom = 0;
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_DEV:
+            if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_FUNC:
+            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
+                switch( *ptr ) {
+                case '\0':
+                    state = STATE_TERMINAL;
+                    break;
+                case '@':
+                    state = STATE_VSLOT;
+                    break;
+                case ',':
+                    state = STATE_OPTIONS_K;
+                    break;
+                }
+                *ptr = '\0';
+                if ( !strcmp(tok, "*") ) {
+                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
+                }else{
+                    if ( hex_convert(tok, &func, 0x7) )
+                        goto parse_error;
+                    pci->vfunc_mask = (1 << 0);
+                }
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_VSLOT:
+            if ( *ptr == '\0' || *ptr == ',' ) {
+                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( hex_convert(tok, &vslot, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_K:
+            if ( *ptr == '=' ) {
+                state = STATE_OPTIONS_V;
+                *ptr = '\0';
+                optkey = tok;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_V:
+            if ( *ptr == ',' || *ptr == '\0' ) {
+                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( !strcmp(optkey, "msitranslate") ) {
+                    pci->msitranslate = atoi(tok);
+                }else if ( !strcmp(optkey, "power_mgmt") ) {
+                    pci->power_mgmt = atoi(tok);
+                }else if ( !strcmp(optkey, "permissive") ) {
+                    pci->permissive = atoi(tok);
+                }else if ( !strcmp(optkey, "seize") ) {
+                    pci->seize = atoi(tok);
+                } else if (!strcmp(optkey, "rdm_policy")) {
+                    if (!strcmp(tok, "strict")) {
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                    } else if (!strcmp(tok, "relaxed")) {
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                    } else {
+                        XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
+                                          " policy: 'strict' or 'relaxed'.",
+                                     tok);
+                        goto parse_error;
+                    }
+                } else {
+                    XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey);
+                }
+                tok = ptr + 1;
+            }
+        default:
+            break;
         }
-        if (*ptr == ',')
-            ptr++;
-        else if (*ptr != '\0')
-            return ERROR_INVAL;
     }
 
-    /* Parse the rest as 'key=val' pairs */
-    while (*ptr != '\0') {
-        char *key, *val;
-
-        ret = parse_key_val(&key, &val, ptr, &ptr);
-        if (ret)
-            return ret;
-
-        if (!strcmp(key, "bdf")) {
-            ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, val, NULL);
-            bdf_present = !ret;
-        } else if (!strcmp(key, "vslot")) {
-            ret = parse_vslot(&pcidev->vdevfn, val, NULL);
-        } else if (!strcmp(key, "permissive")) {
-            pcidev->permissive = atoi(val);
-        } else if (!strcmp(key, "msitranslate")) {
-            pcidev->msitranslate = atoi(val);
-        } else if (!strcmp(key, "seize")) {
-            pcidev->seize= atoi(val);
-        } else if (!strcmp(key, "power_mgmt")) {
-            pcidev->power_mgmt = atoi(val);
-        } else if (!strcmp(key, "rdm_policy")) {
-            ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
-        } else if (!strcmp(key, "name")) {
-            name_present = true;
-            pcidev->name = strdup(val);
-            if (!pcidev->name) ret = ERROR_NOMEM;
-        } else {
-            XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
-            ret = ERROR_INVAL;
-        }
+    if ( tok != ptr || state != STATE_TERMINAL )
+        goto parse_error;
 
-        free(key);
-        free(val);
+    assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
 
-        if (ret)
-            return ret;
-    }
+    /* Just a pretty way to fill in the values */
+    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
 
-    if (!(bdf_present ^ name_present))
-        return ERROR_INVAL;
+    free(buf2);
 
     return 0;
+
+parse_error:
+    free(buf2);
+    return ERROR_INVAL;
 }
 
 int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 {
-#define STATE_TYPE           0
-#define STATE_RDM_STRATEGY   1
-#define STATE_RESERVE_POLICY 2
-#define STATE_TERMINAL       3
-
     unsigned state = STATE_TYPE;
     char *buf2, *tok, *ptr, *end;
 
@@ -262,8 +227,15 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
             if (*ptr == ',' || *ptr == '\0') {
                 state = *ptr == ',' ? STATE_TYPE : STATE_TERMINAL;
                 *ptr = '\0';
-                if (!parse_rdm_policy(cfg, &rdm->policy, tok))
+                if (!strcmp(tok, "strict")) {
+                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                } else if (!strcmp(tok, "relaxed")) {
+                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                } else {
+                    XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s",
+                                 tok);
                     goto parse_error;
+                }
                 tok = ptr + 1;
             }
         default:
@@ -281,11 +253,6 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 parse_error:
     free(buf2);
     return ERROR_INVAL;
-
-#undef STATE_TYPE
-#undef STATE_RDM_STRATEGY
-#undef STATE_RESERVE_POLICY
-#undef STATE_TERMINAL
 }
 
 /*
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index bd8af12ff3..6ab5e47da3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -90,12 +90,12 @@ struct cmd_spec cmd_table[] = {
     { "pci-attach",
       &main_pciattach, 0, 1,
       "Insert a new pass-through pci device",
-      "<Domain> <PCI_SPEC_STRING>",
+      "<Domain> <BDF> [Virtual Slot]",
     },
     { "pci-detach",
       &main_pcidetach, 0, 1,
       "Remove a domain's pass-through pci device",
-      "<Domain> <PCI_SPEC_STRING>",
+      "<Domain> <BDF>",
     },
     { "pci-list",
       &main_pcilist, 0, 0,
@@ -105,25 +105,21 @@ struct cmd_spec cmd_table[] = {
     { "pci-assignable-add",
       &main_pciassignable_add, 0, 1,
       "Make a device assignable for pci-passthru",
-      "[options] <BDF>",
-      "-n NAME, --name=NAME    Name the assignable device.\n"
+      "<BDF>",
       "-h                      Print this help.\n"
     },
     { "pci-assignable-remove",
       &main_pciassignable_remove, 0, 1,
       "Remove a device from being assignable",
-      "[options] <BDF>|NAME",
+      "[options] <BDF>",
       "-h                      Print this help.\n"
       "-r                      Attempt to re-assign the device to the\n"
-      "                        original driver."
+      "                        original driver"
     },
     { "pci-assignable-list",
       &main_pciassignable_list, 0, 0,
       "List all the assignable pci devices",
-      "[options]",
-      "-h                      Print this help.\n"
-      "-n, --show-names        Display assignable device names where\n"
-      "                        supplied.\n"
+      "",
     },
     { "pause",
       &main_pause, 0, 1,
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 867e4d068a..4ebf39620a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1487,10 +1487,10 @@ void parse_config_data(const char *config_source,
              * the global policy by default.
              */
             pci->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_spec_string(config, pci, buf);
+            e = xlu_pci_parse_bdf(config, pci, buf);
             if (e) {
                 fprintf(stderr,
-                        "unable to parse PCI_SPEC_STRING `%s' for passthrough\n",
+                        "unable to parse PCI BDF `%s' for passthrough\n",
                         buf);
                 exit(-e);
             }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index eb29b4e08d..f71498cbb5 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -34,8 +34,7 @@ static void pcilist(uint32_t domid)
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
-               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
-               pcis[i].bdf.func);
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
     }
     libxl_device_pci_list_free(pcis, num);
 }
@@ -55,7 +54,7 @@ int main_pcilist(int argc, char **argv)
     return 0;
 }
 
-static int pcidetach(uint32_t domid, const char *spec_string, int force)
+static int pcidetach(uint32_t domid, const char *bdf, int force)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -66,9 +65,8 @@ static int pcidetach(uint32_t domid, const char *spec_string, int force)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
-        fprintf(stderr, "pci-detach: malformed PCI_SPEC_STRING \"%s\"\n",
-                spec_string);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
     if (force) {
@@ -90,7 +88,7 @@ int main_pcidetach(int argc, char **argv)
     uint32_t domid;
     int opt;
     int force = 0;
-    const char *spec_string = NULL;
+    const char *bdf = NULL;
 
     SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
     case 'f':
@@ -99,15 +97,15 @@ int main_pcidetach(int argc, char **argv)
     }
 
     domid = find_domain(argv[optind]);
-    spec_string = argv[optind + 1];
+    bdf = argv[optind + 1];
 
-    if (pcidetach(domid, spec_string, force))
+    if (pcidetach(domid, bdf, force))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciattach(uint32_t domid, const char *spec_string)
+static int pciattach(uint32_t domid, const char *bdf, const char *vs)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -118,9 +116,8 @@ static int pciattach(uint32_t domid, const char *spec_string)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
-        fprintf(stderr, "pci-attach: malformed PCI_SPEC_STRING \"%s\"\n",
-                spec_string);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
@@ -137,83 +134,72 @@ int main_pciattach(int argc, char **argv)
 {
     uint32_t domid;
     int opt;
-    const char *spec_string = NULL;
+    const char *bdf = NULL, *vs = NULL;
 
     SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
         /* No options */
     }
 
     domid = find_domain(argv[optind]);
-    spec_string = argv[optind + 1];
+    bdf = argv[optind + 1];
+
+    if (optind + 1 < argc)
+        vs = argv[optind + 2];
 
-    if (pciattach(domid, spec_string))
+    if (pciattach(domid, bdf, vs))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static void pciassignable_list(bool show_names)
+static void pciassignable_list(void)
 {
-    libxl_pci_bdf *pcibdfs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
 
-    if ( pcibdfs == NULL )
+    if ( pcis == NULL )
         return;
     for (i = 0; i < num; i++) {
-        libxl_pci_bdf *pcibdf = &pcibdfs[i];
-        char *name = show_names ?
-            libxl_pci_bdf_assignable_bdf2name(ctx, pcibdf) : NULL;
-
-        printf("%04x:%02x:%02x.%01x %s\n",
-               pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
-               name ?: "");
-
-        free(name);
+        printf("%04x:%02x:%02x.%01x\n",
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
     }
-    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
+    libxl_device_pci_assignable_list_free(pcis, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
 {
     int opt;
-    static struct option opts[] = {
-        {"show-names", 0, 0, 'n'},
-        COMMON_LONG_OPTS
-    };
-    bool show_names = false;
-
-    SWITCH_FOREACH_OPT(opt, "n", opts, "pci-assignable-list", 0) {
-    case 'n':
-        show_names = true;
-        break;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
+        /* No options */
     }
 
-    pciassignable_list(show_names);
+    pciassignable_list();
     return 0;
 }
 
-static int pciassignable_add(const char *bdf, const char *name, int rebind)
+static int pciassignable_add(const char *bdf, int rebind)
 {
-    libxl_pci_bdf pcibdf;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_pci_bdf_init(&pcibdf);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcibdf, bdf)) {
-        fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_pci_bdf_assignable_add(ctx, &pcibdf, name, rebind))
+    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
         r = 1;
 
-    libxl_pci_bdf_dispose(&pcibdf);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -223,58 +209,39 @@ int main_pciassignable_add(int argc, char **argv)
 {
     int opt;
     const char *bdf = NULL;
-    static struct option opts[] = {
-        {"name", 1, 0, 'n'},
-        COMMON_LONG_OPTS
-    };
-    const char *name = NULL;
-
-    SWITCH_FOREACH_OPT(opt, "n:", opts, "pci-assignable-add", 0) {
-    case 'n':
-        name = optarg;
-        break;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
+        /* No options */
     }
 
     bdf = argv[optind];
 
-    if (pciassignable_add(bdf, name, 1))
+    if (pciassignable_add(bdf, 1))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciassignable_remove(const char *ident, int rebind)
+static int pciassignable_remove(const char *bdf, int rebind)
 {
-    libxl_pci_bdf *pcibdf;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
+    libxl_device_pci_init(&pci);
+
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    pcibdf = libxl_pci_bdf_assignable_name2bdf(ctx, ident);
-    if (!pcibdf) {
-        pcibdf = calloc(1, sizeof(*pcibdf));
-
-        if (!pcibdf) {
-            fprintf(stderr,
-                    "pci-assignable-remove: failed to allocate memory\n");
-            exit(2);
-        }
-
-        libxl_pci_bdf_init(pcibdf);
-        if (xlu_pci_parse_bdf(config, pcibdf, ident)) {
-            fprintf(stderr,
-                    "pci-assignable-remove: malformed BDF '%s'\n", ident);
-            exit(2);
-        }
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
+        exit(2);
     }
 
-    if (libxl_pci_bdf_assignable_remove(ctx, pcibdf, rebind))
+    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
         r = 1;
 
-    libxl_pci_bdf_dispose(pcibdf);
-    free(pcibdf);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -283,7 +250,7 @@ static int pciassignable_remove(const char *ident, int rebind)
 int main_pciassignable_remove(int argc, char **argv)
 {
     int opt;
-    const char *ident = NULL;
+    const char *bdf = NULL;
     int rebind = 0;
 
     SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
@@ -292,9 +259,9 @@ int main_pciassignable_remove(int argc, char **argv)
         break;
     }
 
-    ident = argv[optind];
+    bdf = argv[optind];
 
-    if (pciassignable_remove(ident, rebind))
+    if (pciassignable_remove(bdf, rebind))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c
index dc49fb7d50..359a001570 100644
--- a/tools/xl/xl_sxp.c
+++ b/tools/xl/xl_sxp.c
@@ -194,8 +194,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh)
         fprintf(fh, "\t(device\n");
         fprintf(fh, "\t\t(pci\n");
         fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
-               d_config->pcidevs[i].bdf.domain, d_config->pcidevs[i].bdf.bus,
-               d_config->pcidevs[i].bdf.dev, d_config->pcidevs[i].bdf.func,
+               d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
+               d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
                d_config->pcidevs[i].vdevfn);
         fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n",
                d_config->pcidevs[i].msitranslate,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55622.96816 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3U-0003oQ-Kp; Thu, 17 Dec 2020 00:22:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55622.96816; Thu, 17 Dec 2020 00:22:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3U-0003oI-Hl; Thu, 17 Dec 2020 00:22:04 +0000
Received: by outflank-mailman (input) for mailman id 55622;
 Thu, 17 Dec 2020 00:22:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3S-0003oD-Gr
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3S-0003pm-CY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3S-0008Qb-9o
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DT2oEZDRrXV3EnbyMaWNug8y+u/7ZZAztZjStIDlNRo=; b=39xL8EMzw2R5gdq3QTMcLlRIcZ
	5pdX9vtuNgSISguGieU4dpGJvrOgkuMqwS68dIScdezaVwHlNRD8F+3rELtyW/n1LwX1Pm2vuoVVW
	pJMBlkWVv1yIsIZuUV68IYkQ+EtNrJ/WUfPOaDN7mQgKT/ALuIlw+wQZV9SwEpj2DRw4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kph3S-0008Qb-9o@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:02 +0000

commit feeafa007b804cdf2406c50a6515ee0a217d3438
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:33:43 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:33:43 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55623.96820 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3d-0003ow-Mn; Thu, 17 Dec 2020 00:22:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55623.96820; Thu, 17 Dec 2020 00:22:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3d-0003om-JU; Thu, 17 Dec 2020 00:22:13 +0000
Received: by outflank-mailman (input) for mailman id 55623;
 Thu, 17 Dec 2020 00:22:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3c-0003oh-JY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3c-0003pp-HD
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3c-0008RD-Ek
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JuFf7LKJIACNIrrdNwiCsrwtpveNwI1tenZx9emaeyQ=; b=tl7b4YtOa+VOMmAKbX2b4dj4W/
	9Br145v/Y9GaSQnewpPpdQpE9p9ACUzn9MQTTJrGEmMYzn8+xbTH4XAXQxiqsFHylGj1CrpgDaVB0
	9mMjBiPj5EhGyX57v0OQpD7PpzAOWYvPIHQwKcTZKSV5IUau9ODsLjSjoTcpnE35Kh1g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kph3c-0008RD-Ek@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:12 +0000

commit 705c7d89565fc2f7d06a255a4a76c6642340dbe2
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:35 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:35 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4be374d3f..7bf1123da3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -413,7 +413,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -423,7 +424,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -451,14 +452,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -992,7 +994,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1032,7 +1034,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1108,7 +1110,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1247,7 +1249,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1505,7 +1507,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 1df6ad94ab..53aafa1d9b 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -146,7 +146,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55624.96824 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3n-0003qI-OI; Thu, 17 Dec 2020 00:22:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55624.96824; Thu, 17 Dec 2020 00:22:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3n-0003qA-LH; Thu, 17 Dec 2020 00:22:23 +0000
Received: by outflank-mailman (input) for mailman id 55624;
 Thu, 17 Dec 2020 00:22:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3m-0003px-Mc
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3m-0003py-Li
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3m-0008S2-JX
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6fX/lK6FsYDYgjJIcZKD/n7bI3M/gNj42pusIUDccGQ=; b=jhv+F/2iNnHnKJb2kuCLI7k8v3
	1MTy+ZbOv149TuJeRbp2PUwXyMxMIQNvj6192g0fiQFay43FD2sVEq8uFQG1dRt6s3cte4CrsHm8O
	NOC54Qkus2WP26Q0BLalKneK3dj08dgSHNWXY3TabAYO+yxWnsdQ1ePH1iJnJqZwu+co=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kph3m-0008S2-JX@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:22 +0000

commit 09a4146bdcf8eea804dd90fee4b9132bdbf69bae
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:37 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 7bf1123da3..3471ce1592 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1261,13 +1261,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1289,7 +1293,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1304,7 +1308,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1313,12 +1324,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55625.96828 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3x-0003rn-Pz; Thu, 17 Dec 2020 00:22:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55625.96828; Thu, 17 Dec 2020 00:22:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph3x-0003rf-Mz; Thu, 17 Dec 2020 00:22:33 +0000
Received: by outflank-mailman (input) for mailman id 55625;
 Thu, 17 Dec 2020 00:22:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3w-0003rY-Pa
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3w-0003qA-Om
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph3w-0008Sc-Nl
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xsspFJoGSroUtDH7KOWJzkPHP1FfFzITukL1rn82psg=; b=U6I8W5no3m7wVdrm3AYpwqRC7o
	wRdUvsVwhi4bdme4YtyN86/rMlN3w/9v++peIuvYZl3D7dp4s4YGMYlfJsJWlYB5Y5u4zml6w+mb3
	2h011eHbokLZW63HRxjIB8wgXnBdIcFqtCYLVyTQDgDGWkAz2IdTEgmuT7IQSyRY10JE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kph3w-0008Sc-Nl@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:32 +0000

commit 0bfb2101f243b27611ffec2087559d816d591e63
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:40 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:40 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3471ce1592..476e69d658 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -918,11 +918,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -955,7 +950,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -975,6 +969,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -991,18 +988,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55626.96832 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph47-0003t0-SA; Thu, 17 Dec 2020 00:22:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55626.96832; Thu, 17 Dec 2020 00:22:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph47-0003sn-OY; Thu, 17 Dec 2020 00:22:43 +0000
Received: by outflank-mailman (input) for mailman id 55626;
 Thu, 17 Dec 2020 00:22:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph46-0003sf-SZ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph46-0003qL-Rm
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph46-0008TG-Qm
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8wP1tyZszd/uaQ/px2VOKKzkySQG8LpKjNPRF0V1Ey8=; b=rBXR5Zx7LJgVMbuuRqMDC8xO3x
	/3cqOl8fe3Co+34l+kzYWUamegO5xgk8B6QHEd/mX7MYx6qSPfXO1MUh3SDF0h6ixKf0Zu52BPdea
	aErzIEPj2zAas3KuP81h4QnCV35fl1tS5OqIjbycHVztQvvQvL0odgETK9+qIY3/Brpc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kph46-0008TG-Qm@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:42 +0000

commit d3f8c086d23d886e2f5357b096bfefd5c8e5bcc4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:42 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:22:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:22:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55627.96836 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4H-0003uZ-TK; Thu, 17 Dec 2020 00:22:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55627.96836; Thu, 17 Dec 2020 00:22:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4H-0003uR-QE; Thu, 17 Dec 2020 00:22:53 +0000
Received: by outflank-mailman (input) for mailman id 55627;
 Thu, 17 Dec 2020 00:22:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4H-0003uK-0U
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4G-0003qj-Vx
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4G-0008U2-UG
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:22:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BB5a8gSyfIiFthNJW2U2Zely+YijEhSm4IIUQCdPxh4=; b=IyYTbLQqel+lW3IZe0gSt50q+k
	2MBGrYRdMUbnRb2E+P8uWxxPLWzr5FcA/bYMwsMw2GkVdiRv01LPSx5EKtk0VtpJLDwIW8VOgRCei
	dUEoE/9eqIx1IFwjVtDS4HT0Q5r9MTY7Clw0new1mThMiSeliadYI+UmZuNvyij69Bo8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kph4G-0008U2-UG@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:22:52 +0000

commit fa2307be61df52970e7ee47a6c55124155c173c6
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:45 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  9 ---------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 476e69d658..3d0e7b3917 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1276,8 +1276,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1287,8 +1289,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1297,9 +1301,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1327,6 +1333,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index a2f144f6dd..364ad8ea63 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -372,9 +372,6 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
 	domid = atoi(vec[0]);
 	/* Ignore the gfn, we don't need it. */
 	port = atoi(vec[2]);
@@ -438,9 +435,6 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn))
-		return EACCES;
-
 	domid = atoi(vec[0]);
 	tdomid = atoi(vec[1]);
 
@@ -473,9 +467,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55628.96839 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4R-0003wR-W6; Thu, 17 Dec 2020 00:23:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55628.96839; Thu, 17 Dec 2020 00:23:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4R-0003wI-T6; Thu, 17 Dec 2020 00:23:03 +0000
Received: by outflank-mailman (input) for mailman id 55628;
 Thu, 17 Dec 2020 00:23:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4R-0003wA-4D
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4R-0003rB-3T
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4R-0008Ur-20
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7T0q0mBSGkKigYZX0vk3pPDVY6f1b+Ga6PcmGlJf7/A=; b=3XO3FZ7g0eKchQAwJoJpW2Fo92
	iG/ZG+/mWtvUdIP54NoLU98AnpzK+UwdEnadD+OEmhYZASGaOmQed5+SdYOLlzU2rjN2YEr7AI4F/
	svSelYKppRLZyoqdrRX6yhbHMJG/zyOYdDK0D5ymUe3l1pd49czJM6LfXARPp9NQQPOg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: rework node removal
Message-Id: <E1kph4R-0008Ur-20@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:03 +0000

commit 297f209636d89ca5bfe2b91accfdf0dc1b922779
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:48 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3d0e7b3917..c74413bda2 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1080,74 +1080,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1158,11 +1160,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1200,7 +1204,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55629.96844 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4c-0003xl-1g; Thu, 17 Dec 2020 00:23:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55629.96844; Thu, 17 Dec 2020 00:23:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4b-0003xd-Ug; Thu, 17 Dec 2020 00:23:13 +0000
Received: by outflank-mailman (input) for mailman id 55629;
 Thu, 17 Dec 2020 00:23:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4b-0003xW-7y
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4b-0003rL-6n
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4b-0008VW-5l
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HgRL2WVGpAyJpMIERbrb3cTMu9cmMGpsL9WzkP8MgeI=; b=2dLet1vvAbY2i+GSPmoC1/l4bR
	O66PMKCTGjb9l6BkoBnBQXwY7BOn7Tj9v6GmwqZQ8UuyQg1rnbq3RRNz70ax9QRPBfbchL4A8ZfwE
	wgeuSC9mYRuNgTfdz5E/S8wQPQdvc/CEF3oKRZkIPgBCmLc3YZHdlGDyjxajFkheywYo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kph4b-0008VW-5l@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:13 +0000

commit 1e5815697f941d57fbdc81d0e973a00692adfad3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:50 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c74413bda2..b39610c876 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1111,8 +1111,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1124,7 +1124,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1136,6 +1136,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,8 +1166,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55630.96848 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4m-0003z2-3M; Thu, 17 Dec 2020 00:23:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55630.96848; Thu, 17 Dec 2020 00:23:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4m-0003yt-03; Thu, 17 Dec 2020 00:23:24 +0000
Received: by outflank-mailman (input) for mailman id 55630;
 Thu, 17 Dec 2020 00:23:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4l-0003yl-Aq
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4l-0003rW-A4
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4l-0008WA-96
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=X6t22sR0zjW3njpv/mnj9K9R1Nd7eMSo9xIwDNn2t88=; b=2e+/qmHV1Go00Z54l1lVOibkxs
	TeUtFPNa/TTmgQ3H2yZrzNGqPxZi2n+R0e5HXf2zWYvbbebogOnjo+nAj+V8ydE8bqbUY5iJQxKEx
	GaKJFrnyxJ1NhY5PjPQFSXCx/pH7lIeS+9JoxnnM0oa7nI4Br9i9Z4KImW0VQHreHy5g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: introduce node_perms structure
Message-Id: <E1kph4l-0008WA-96@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:23 +0000

commit 53dabb1fdb30788f9e1826c3543ecf19d37d60d4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:53 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:53 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b39610c876..06e937de66 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -397,14 +397,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -421,7 +421,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -433,12 +433,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -464,23 +465,22 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -527,7 +527,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -573,8 +573,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -750,16 +749,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -938,13 +936,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1221,7 +1219,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1232,13 +1230,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1249,21 +1246,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1536,8 +1533,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53aafa1d9b..a291f15ce7 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -106,6 +106,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -117,8 +122,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 364ad8ea63..76bdd46c8d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -650,12 +650,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -676,12 +676,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55631.96852 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4w-00040I-4v; Thu, 17 Dec 2020 00:23:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55631.96852; Thu, 17 Dec 2020 00:23:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph4w-00040A-1p; Thu, 17 Dec 2020 00:23:34 +0000
Received: by outflank-mailman (input) for mailman id 55631;
 Thu, 17 Dec 2020 00:23:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4v-000403-Ez
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4v-0003re-DP
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph4v-000058-CW
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DmwnXN28YDhi5WFLb7iyOdwuQjgBy0lwsdy8L1rDCUs=; b=Cz+q9T4zsdB39uSQOCFzqoT6e8
	UloOYzVCQIrmdEtS4KXCV5seVl4sv1YTxmVZ4pRSdmH3WOx/DUVwv4eX0fIkkj+d2iq7BnNsh47S/
	sPgt7MkGNFZx+uGwQP6V3rEUSSoD1XhbSSgd3+tyL/dE/9xvIk4XageLyN9N+gusRavA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kph4v-000058-CW@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:33 +0000

commit 190ddd3403bad28167a070388a904b02b956093c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:56 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index cb8009cb68..2081f20f55 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See https://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 06e937de66..1db9d0cc31 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -464,8 +464,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1238,22 +1238,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a291f15ce7..3f958c29ab 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -162,6 +162,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 76bdd46c8d..e1106d90b6 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -576,6 +579,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -597,6 +653,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55632.96855 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph56-00041k-7x; Thu, 17 Dec 2020 00:23:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55632.96855; Thu, 17 Dec 2020 00:23:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph56-00041d-54; Thu, 17 Dec 2020 00:23:44 +0000
Received: by outflank-mailman (input) for mailman id 55632;
 Thu, 17 Dec 2020 00:23:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph55-00041Y-IJ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph55-0003rt-Gh
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph55-00005u-Fn
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HejisNHTu7pnnR1KBczq4/iJpqoRSR/eVxRVJMTpGwI=; b=VW5pcqOrX2nXxWIa67mxBFJ2Bd
	Sd2tgA+BrTecfkF8mG9Kn7LP4DrjJFykTvQgsC2cyvdDthn6ll8GhIVPWbYFb6pyP/PgoUlCuqpqI
	3pDgy4wbnZ03kPw0aIzET3rBq1J9pc/QroN/18GLFUUJjFw/4DemngRZaIFuxKtm8H0I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kph55-00005u-Fn@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:43 +0000

commit e47f438df3bdffe213b6bd28245504c8c7fe367a
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:34:58 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:34:58 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1db9d0cc31..ad1903c555 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -354,8 +354,8 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -487,7 +487,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -559,10 +559,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1049,7 +1049,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1071,7 +1071,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1134,7 +1134,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1158,13 +1158,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1230,7 +1231,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1266,6 +1267,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1273,7 +1275,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 3f958c29ab..6c21d5bb9a 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,15 +149,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -168,6 +170,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e1106d90b6..cf239c044b 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -202,7 +202,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -240,7 +240,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -401,7 +401,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:23:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:23:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55633.96860 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5H-00043L-A1; Thu, 17 Dec 2020 00:23:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55633.96860; Thu, 17 Dec 2020 00:23:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5H-00043D-6l; Thu, 17 Dec 2020 00:23:55 +0000
Received: by outflank-mailman (input) for mailman id 55633;
 Thu, 17 Dec 2020 00:23:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5F-000435-Ke
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5F-0003sK-Ju
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5F-00006c-J0
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:23:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ma9igq0v23vqkZlElXcWCzE2obu/mttQZYItnwPJcqo=; b=0KzTn4Z8GxR5fMym8mvmJJWhJx
	9DSSj9+kPutfQbKRHkOg/k/wcwHLEAp3fXlIWKesM1GT21bo+gLuUoUIx0lwpZcMW23UHRMpR1J3l
	Crd3FMecSfwSMDBbarbj9I46H9tF225Z++pnCU+Ue5VNP4B0DRtlr/SZcgvaSxe36G+c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kph5F-00006c-J0@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:23:53 +0000

commit f40d933da4d689ef9b62d7479540ad1be36e0dad
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:06 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:06 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55634.96864 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5R-00044X-BH; Thu, 17 Dec 2020 00:24:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55634.96864; Thu, 17 Dec 2020 00:24:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5R-00044P-8G; Thu, 17 Dec 2020 00:24:05 +0000
Received: by outflank-mailman (input) for mailman id 55634;
 Thu, 17 Dec 2020 00:24:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5P-00044G-PB
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5P-0003sh-OY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5P-00007Q-M7
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=3Seklv9/F+2Ckzs/FEV6Y9XPyZKcjhipe/31xOffCqA=; b=0h23ub1e7rkWPMoxawJQQkI/9e
	8sN1a4+9rClbrY1H8pEiSmAUfVmSd/0wWJ+1UtYnOyFFRFtUCeEQa+5mgVPNrGrgf1NCdsMEraTRQ
	ogMaSrzwoI4maRxMDkOlYECCPtChPmEk2XV7O3Wu8TdYWTzIvR5E7oBP7RfaaoxZ0MkA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kph5P-00007Q-M7@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:03 +0000

commit 67bfd6cd4b1b44882f2a549a8750e278338436e9
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:08 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55635.96868 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5b-00045o-Cw; Thu, 17 Dec 2020 00:24:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55635.96868; Thu, 17 Dec 2020 00:24:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5b-00045g-9l; Thu, 17 Dec 2020 00:24:15 +0000
Received: by outflank-mailman (input) for mailman id 55635;
 Thu, 17 Dec 2020 00:24:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5Z-00045Y-SP
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5Z-0003so-Rm
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5Z-000085-Qy
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gzxUMWOPHV7uAwDqm1cvf1nFxZJOeLviAN7mWOG6VDM=; b=qslhX+hf9Xfic5vSkRkXZANMWP
	2x6TmCZvYpWqE+TIf3HhIPfaMiu/lyC/6+pRutVLeJeRKSLcm8uSpdw7Mh0rrMetlUfOGyVLRWXV/
	qxFGvKnggE63SHv0xOpI5XgVOQaXBUnOKcJV4B5lR7vj5NuIP3z7EOxtMbmqnEOLN1dM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kph5Z-000085-Qy@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:13 +0000

commit 0911dfad0fbadee2ffaf1da1a8c596b750fd21d4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:11 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55636.96872 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5l-000475-EU; Thu, 17 Dec 2020 00:24:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55636.96872; Thu, 17 Dec 2020 00:24:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5l-00046w-BF; Thu, 17 Dec 2020 00:24:25 +0000
Received: by outflank-mailman (input) for mailman id 55636;
 Thu, 17 Dec 2020 00:24:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5k-00046l-09
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5j-0003sw-VJ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5j-00008r-U6
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fy1Tfj21S+vn4p8r32CzwBU7dm1vBKPfPSzEiMMgqmc=; b=S91JJBXftBaTsD6ujnWd6kbnYI
	lnzSBrfByVyg8J7VmH0nKZG/61NZV5lFsZLnzD45J2NsFgDCudAcuWt12bjuuIbX9I/ux0CmNrdWn
	0w4MzCOs6IAEAVU7k8lqcMvs+w0VUOuhTyWalPIr1nxYfLFNP40h1Zi3wK+1kf2hzoxU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kph5j-00008r-U6@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:23 +0000

commit cf4116c38c0d3ab83cdaac7a23bc8598362c410d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:13 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:13 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 7e7824761b..8d0c50bfa4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -286,6 +286,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -335,7 +337,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55637.96875 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5v-00048Z-H5; Thu, 17 Dec 2020 00:24:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55637.96875; Thu, 17 Dec 2020 00:24:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph5v-00048S-E6; Thu, 17 Dec 2020 00:24:35 +0000
Received: by outflank-mailman (input) for mailman id 55637;
 Thu, 17 Dec 2020 00:24:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5u-00048J-33
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5u-0003t9-2G
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph5u-0000A1-1V
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yMScd7CkpF5SXusZKNzho8Z0IHA9yDeCK6u+Ofck/VI=; b=xAVeInYPH6ORdeZmX4UpXlze/l
	Lkg3ZZ6dmw1hkS0Nw292/6G1UnzfpTKrQpMNq9SgNtsAJWxcyeM5Rpx47YdIA/Y6HZqysq/HAl/3W
	JFBbePfs5YHtgxAa0/yKbmWvnT9wFRkehLydgXmR2CBpH346eKcRBLd3Tp1FOjH9o+AQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kph5u-0000A1-1V@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:34 +0000

commit ff3d2dff9b80929c91e157b12947be29b50348b6
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:16 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f2c4318c88..9f9f7ee2f0 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 8d0c50bfa4..f7b88065bb 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -337,7 +337,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55638.96880 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph65-00049l-J3; Thu, 17 Dec 2020 00:24:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55638.96880; Thu, 17 Dec 2020 00:24:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph65-00049e-Fs; Thu, 17 Dec 2020 00:24:45 +0000
Received: by outflank-mailman (input) for mailman id 55638;
 Thu, 17 Dec 2020 00:24:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph64-00049W-5y
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph64-0003tS-5G
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph64-0000Ao-4T
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xwyHTyI+J3rAzICo4yTf3m7lTaUQNBv1HuSSlODfj0E=; b=awN1p7gk+sLd4hisrJC4QR2668
	zynw1SZSYx+oHU7Eo+IpC7JvTTvUkg/Ov1GRhx6zkYDzDF3dX31iDSbzYMIRgDk1XGC4HZXt0i9cO
	ymkkgfOtj7aLRUCtXCxrxHc10UdF0AnAEicOL/KBJZoUtjpdtXBemjKQ6khHYYjRgMm8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kph64-0000Ao-4T@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:44 +0000

commit 34f008318d191dfee1f58be710438fda5a8fc914
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:35:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:35:19 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index f7b88065bb..0d355bbcb8 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:24:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:24:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55639.96883 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6F-0004BH-Kh; Thu, 17 Dec 2020 00:24:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55639.96883; Thu, 17 Dec 2020 00:24:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6F-0004BB-Hg; Thu, 17 Dec 2020 00:24:55 +0000
Received: by outflank-mailman (input) for mailman id 55639;
 Thu, 17 Dec 2020 00:24:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6E-0004B3-97
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6E-0003to-8L
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6E-0000BZ-7Y
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:24:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=757nXRUdQzhFSDhetPOWTkbVWy17lRi9loKphSwpPZ4=; b=A5h5Ms7n5u+qgn+vi0wsIbDWhG
	N2+TmUlXCsTO45QiH++wDgtndH/aofx9BTkvKkrCOD/QsXFmeMgiA9kUAaOnbYrjwa6pTZgT29iyQ
	40c0wNUY/CwNdwVlxVpXO15gZ1pluh6k3bCDocHtuEfsj3tRDayajMDO9dkcSjzTHA0M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kph6E-0000BZ-7Y@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:24:54 +0000

commit 496306324d8d933a811cbd3cbfded4cc45034a32
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:36:01 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:01 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/include/xenstore_lib.h           |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/include/xenstore_lib.h b/tools/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/include/xenstore_lib.h
+++ b/tools/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ad1903c555..cbefe4c819 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -403,8 +404,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -420,6 +426,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -476,8 +485,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1239,8 +1249,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1879,6 +1893,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1899,6 +1914,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1921,7 +1937,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -1963,6 +1979,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index cf239c044b..7169da9851 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -67,8 +67,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -188,6 +194,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -209,21 +218,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -289,58 +311,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -383,15 +431,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -497,8 +551,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -641,8 +695,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -729,6 +785,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 9f1dc6d559..80c03acbea 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -146,7 +146,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55642.96903 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6Q-0004FJ-2i; Thu, 17 Dec 2020 00:25:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55642.96903; Thu, 17 Dec 2020 00:25:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6P-0004FB-Vy; Thu, 17 Dec 2020 00:25:05 +0000
Received: by outflank-mailman (input) for mailman id 55642;
 Thu, 17 Dec 2020 00:25:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6O-0004Eo-CP
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6O-0003uC-Bk
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6O-0000E9-Aq
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=btj05Tj8AhizjQ5OjS7NazkO5MKZiaCxhLi2c1FUcRk=; b=IguRh+BIsNaV6vKI1MTH+l37qt
	A/My1ZGznI47j3GflIRoXAL8TLXwmiI4WDR/aOiQK3dcGbvNTL/xTnD8zVSKiGnMUaOnQZDu43AJX
	aFbBJoo1sQy9+lJfbQ/X3hkmerPFp3j1XmB8QMzVfvCF9paD6GAq8BHb8pgvOvJl6ghw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kph6O-0000E9-Aq@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:04 +0000

commit c46eff921209a2526f0055cdb76fbf69176b729e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:36:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:04 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 0d355bbcb8..ff9fbbbac2 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -336,6 +336,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55644.96907 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6a-0004IS-4j; Thu, 17 Dec 2020 00:25:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55644.96907; Thu, 17 Dec 2020 00:25:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6a-0004IK-1E; Thu, 17 Dec 2020 00:25:16 +0000
Received: by outflank-mailman (input) for mailman id 55644;
 Thu, 17 Dec 2020 00:25:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6Y-0004Hv-GH
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6Y-0003uJ-Fc
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6Y-0000Fm-EK
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=oAqhoB3teLFb23jIE+FRgbKqNn+POakvAXDzbnPoN8U=; b=WJAF5xkk5k1RarcKOTYd87EhYb
	k4oS3ThzZYtVJGU85LFrD7uClwKPG+lsYycHNLRwpzTnqnR+hN2eo34Fa2iR1IM73r8KiVAJulr2T
	9UK+KznIPXtck+VrQl60nSIZc6EwCf2lHJgNHZn0J09920dZOGzpvCeU2wvoT3WP5iRU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kph6Y-0000Fm-EK@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:14 +0000

commit bf0703992c62d89e30a9051c363055387257f24f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:36:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:39 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index ea9e1b7620..ebe18b8e31 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -31,6 +31,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index ff9fbbbac2..39d6d767e4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55647.96911 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6j-0004Kh-6I; Thu, 17 Dec 2020 00:25:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55647.96911; Thu, 17 Dec 2020 00:25:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6j-0004KY-38; Thu, 17 Dec 2020 00:25:25 +0000
Received: by outflank-mailman (input) for mailman id 55647;
 Thu, 17 Dec 2020 00:25:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6i-0004KS-KG
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6i-0003uR-JY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6i-0000Gf-IL
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KRAteNZFnLzga1aSmX/LavfQtIj2UyFGVwWo8Qkz/EE=; b=YiYEUfdmGV9VmkGfFAhBTxPuw7
	zTuLHmVyQfEqFncpv+hTYmW/aAN/xRCRVFd22KVPflDMsqhWVnv/KhKBti2Alx/arbi4XB6DAzcVt
	PO2xAmI1LBlLE8XMsdKsfgRAaT1pJUk94CxMtAnt+x1rE/XMxEPGHDzZGMtF/o41TWX8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kph6i-0000Gf-IL@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:24 +0000

commit 5a3f7a05a3680a52d52053fa0a3ce9afea5b8c81
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 13:36:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:42 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cbefe4c819..c929cbbc3b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -673,6 +673,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55649.96915 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6t-0004MH-8A; Thu, 17 Dec 2020 00:25:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55649.96915; Thu, 17 Dec 2020 00:25:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph6t-0004M7-4m; Thu, 17 Dec 2020 00:25:35 +0000
Received: by outflank-mailman (input) for mailman id 55649;
 Thu, 17 Dec 2020 00:25:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6s-0004M0-NW
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6s-0003ug-Mr
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph6s-0000He-Lt
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=47eX1immDaiJhM8Qk7qdDlG+QngI9+6twGtXPkCNu9g=; b=p0QTxLOG1qol++WBBqmR/7xIu6
	zy3RPe8RL13yBpqQm+fpbF1+5T99yuezPvSRXxoCz+IJ2jV42HcPjfwZ83H6c5wWeg12y0s80S23W
	bSqP4OMzvjw10WQldyFZfG6kj8MiqRhzEspGUF7K5aJ0GIY8Kn5LhpmBK8+TF5MRMeq8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kph6s-0000He-Lt@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:34 +0000

commit d2fa370d3ef9cbe22d7256c608671cdcdf6e0083
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 13:36:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:36:45 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c929cbbc3b..746a1247b3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1337,6 +1337,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1395,8 +1421,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1453,14 +1481,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1475,6 +1503,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->pollfd_idx = -1;
 	new->write = write;
 	new->read = read;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2136,8 +2165,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2149,8 +2179,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 6c21d5bb9a..4c6c3d6f20 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -77,6 +77,9 @@ struct connection
 	/* Who am I? 0 for socket connections. */
 	unsigned int id;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7169da9851..7d348d57f3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -286,6 +286,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -303,6 +307,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55650.96919 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph73-0004O5-9c; Thu, 17 Dec 2020 00:25:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55650.96919; Thu, 17 Dec 2020 00:25:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph73-0004Nw-6N; Thu, 17 Dec 2020 00:25:45 +0000
Received: by outflank-mailman (input) for mailman id 55650;
 Thu, 17 Dec 2020 00:25:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph72-0004Nr-Qg
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph72-0003ur-Py
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph72-0000IY-P3
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vVW+0xw828m3LAc1EKd1aa52xeiLj0v2otnHenPDZbw=; b=Onafd9VrF9X/UltgjwOmpTjNY4
	f2r6soCiQ73tjgJUMD8KDE5x2NnMXhc2qzY7frK++tPBQ6XXu/YRoZiKsJorFOa2bU2FX0nhFfLcW
	CDoJ7uL5XSgPi4bFump83qRlglZpDAfmSFbU5tsZfmxCXh0dgILsrYXRz4w7g18s+Pmc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kph72-0000IY-P3@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:44 +0000

commit 491a077ed4c51f26ee77bc92ca346942482cf24e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:37:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:37:14 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 9f9f7ee2f0..6ee3552ec2 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:25:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:25:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55651.96922 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7D-0004Pn-CJ; Thu, 17 Dec 2020 00:25:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55651.96922; Thu, 17 Dec 2020 00:25:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7D-0004Pg-9N; Thu, 17 Dec 2020 00:25:55 +0000
Received: by outflank-mailman (input) for mailman id 55651;
 Thu, 17 Dec 2020 00:25:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7C-0004Pb-Tj
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7C-0003vI-T1
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7C-0000JG-S2
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:25:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=i97FhoL2MHAHlbu4dcsoyJlBY7dNyINPK18FyIWmTgI=; b=W5/sIVjVqkpzfmmdbKwwphdqH+
	DcFdM3u2lcnXekH/ChTWzm1NzrD/q7W/gbOHvkoW+T5ZdqLaqdbzdbzaxIJcTBiQer+C8Vc9bdt+E
	NUbvKLaJRE0CRQJByFzZWQL0LySKCeyE2azkGW0jpqRF/JPso2tJAPLUlAbzEQMhdUkM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kph7C-0000JG-S2@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:25:54 +0000

commit 2a3f8d12f00ea87c8ac84b8a2f84d1afe42230f3
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 13:37:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:37:33 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55652.96927 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7O-0004RP-E1; Thu, 17 Dec 2020 00:26:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55652.96927; Thu, 17 Dec 2020 00:26:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7O-0004RH-B6; Thu, 17 Dec 2020 00:26:06 +0000
Received: by outflank-mailman (input) for mailman id 55652;
 Thu, 17 Dec 2020 00:26:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7N-0004R7-0w
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7N-0003xA-0F
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7M-0000KC-Vl
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KNeManKEW6+rVVLDsPUsHZfyfdiXVwRmOqPWE6xcdhU=; b=xAIGa70k3uY+cdzbiEHZdr0FJQ
	UFHzPllGFOUMYZqqQYC4zJ0IiuwxasSCmDSDITkBelDTVc591Gdjl9cXldGGM2YAESnkjGA93k16m
	9Whil8TSPR2n56KTEgSVb0ZuNk0zf/BUA/LbobUvCK7chF3fersDKpfpeSCa7O2PQZU8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kph7M-0000KC-Vl@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:04 +0000

commit e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:40:27 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:40:27 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 1b894d0124..6d3561ea77 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index cfea5b5523..e41330ca55 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1036,7 +1036,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ca94c2bedc..a71b935c10 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1909,7 +1909,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 663e76c773..27dc0f8ed7 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -113,7 +113,7 @@ static int parse_pcid(const char *s)
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 30d6f375a3..1a2e5e41ab 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -676,7 +676,7 @@ static void __init noreturn reinit_bsp_stack(void)
         asm volatile ("setssbsy" ::: "memory");
     }
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 861a227dbd..81ceafce98 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1635,6 +1635,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 51a4cdbf7c..b47addb3c8 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,13 +155,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
             "jmp %c[fun];"                                              \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
@@ -176,12 +176,6 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55653.96931 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7Y-0004Sj-Fs; Thu, 17 Dec 2020 00:26:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55653.96931; Thu, 17 Dec 2020 00:26:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7Y-0004SZ-Ca; Thu, 17 Dec 2020 00:26:16 +0000
Received: by outflank-mailman (input) for mailman id 55653;
 Thu, 17 Dec 2020 00:26:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7X-0004SR-45
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7X-0003xI-3M
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7X-0000Kt-2W
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=45srhEQyHigHIM3eAqTLuWzsgOi632vAQwjNDZcbSlI=; b=peBrzacIyR+ptLM6d4i6olIzb7
	oeFEzY/tIxbU2TPL0koFppvAfkRIX8XIGy9PRUTu/NvioIUsJXLKSC4Ux9XPOoUiKEfY2yxUP92id
	9W4QNHgMimoXlo26AonaFN+1ghGfpgGWqxrPFHURlxMge4oRyv+12oAvGLr5KipBTqaM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kph7X-0000Kt-2W@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:15 +0000

commit 058e469ab4d5cc5959423aafd6ba181dfc310a7f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:41:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:41:09 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 6d3561ea77..3f8d8be280 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55654.96934 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7i-0004UH-H9; Thu, 17 Dec 2020 00:26:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55654.96934; Thu, 17 Dec 2020 00:26:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7i-0004U9-E4; Thu, 17 Dec 2020 00:26:26 +0000
Received: by outflank-mailman (input) for mailman id 55654;
 Thu, 17 Dec 2020 00:26:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7h-0004Tx-7u
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7h-0003xR-78
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7h-0000Li-6D
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HxNv+jxoib3qks56JE5vCEBhskVFNop83JLpG5D2aP4=; b=TousQ5KV074A5Bu3iWmaubz4Qk
	qSfsPKaUKd/JipK/XST0yd7ZswS5XoT0ysAni/K12ksqUYKLpBQpZ5CUq6RcRmaCpVsFiiuNSwevZ
	BJrLUgJ7J26P0+I/VON+puOe+DCQhri+iN650oU93TuTtkQY/uaAVH8l1+MaJw2CvgR4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kph7h-0000Li-6D@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:25 +0000

commit e6ebd394385db52855d1517cea829ffff68b34b8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:41:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:41:23 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 3f8d8be280..4932ed62f1 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -710,7 +705,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -2047,20 +2042,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index e41330ca55..d90627d4f7 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -991,8 +991,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a71b935c10..1466064d0c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,8 +1850,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 27dc0f8ed7..1a607f856e 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,7 +110,7 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index b47addb3c8..4d8822f78c 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -155,18 +155,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-            "jmp %c[fun];"                                              \
+            instr "[fun]"                                               \
             : [val] "=&r" (tmp),                                        \
               [ssp] "=&r" (tmp)                                         \
             : [stk] "r" (guest_cpu_user_regs()),                        \
-              [fun] "i" (fn),                                           \
+              [fun] constr (fn),                                        \
               [skstk_base] "i"                                          \
               ((PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8),               \
               [stack_mask] "i" (STACK_SIZE - 1),                        \
@@ -176,6 +176,13 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index df657dc69f..3900d7b48b 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -337,7 +337,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 111ccd7e61..09ea0fa2cd 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 struct hvm_emulate_ctxt;
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55655.96940 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7s-0004Vf-JP; Thu, 17 Dec 2020 00:26:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55655.96940; Thu, 17 Dec 2020 00:26:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph7s-0004VV-Ff; Thu, 17 Dec 2020 00:26:36 +0000
Received: by outflank-mailman (input) for mailman id 55655;
 Thu, 17 Dec 2020 00:26:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7r-0004VL-BE
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7r-0003xb-AY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph7r-0000MY-9k
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QjuULVnkyCPxn6Cj6acIlzfviKhVi+FNBY2qRW5gn4U=; b=FLaQw3JeUoKW3q4jHLJcy3/vSR
	D3sFiJp6OWSvC9WFwRVU6K0ZP64CcCJVIMruLVphcpjW7etCkGbhEbZJI+qWs57ORyuy2jzg/dZrv
	kyhs64S/HWfIANC/FhbDr4eO9TU316gH5c3tJLcQd9gw1wZCgOCv3myTI12soJqprNE4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/irq: fix infinite loop in irq_move_cleanup_interrupt
Message-Id: <E1kph7r-0000MY-9k@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:35 +0000

commit ca85682e8c16361fdf3814c9b25a2ec3ff4f8bed
Author:     Roger Pau Monné <roger.pau@citrix.com>
AuthorDate: Tue Dec 15 13:42:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:42:16 2020 +0100

    x86/irq: fix infinite loop in irq_move_cleanup_interrupt
    
    If Xen enters irq_move_cleanup_interrupt with a dynamic vector below
    IRQ_MOVE_CLEANUP_VECTOR pending in IRR (0x20 or 0x21) that's also
    designated for a cleanup it will enter a loop where
    irq_move_cleanup_interrupt continuously sends a cleanup IPI (vector
    0x22) to itself while waiting for the vector with lower priority to be
    injected - which will never happen because IRQ_MOVE_CLEANUP_VECTOR
    takes precedence and it's always injected first.
    
    Fix this by making sure vectors below IRQ_MOVE_CLEANUP_VECTOR are
    marked as used and thus not available for APs. Also add some logic to
    assert and prevent irq_move_cleanup_interrupt from entering such an
    infinite loop, albeit that should never happen given the current code.
    
    This is XSA-356 / CVE-2020-29567.
    
    Fixes: 3fba06ba9f8 ('x86/IRQ: re-use legacy vector ranges on APs')
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/irq.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index f82c93dfdc..768a8fc7c9 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -448,8 +448,15 @@ int __init init_irq_data(void)
     set_bit(HYPERCALL_VECTOR, used_vectors);
 #endif
     
-    /* IRQ_MOVE_CLEANUP_VECTOR used for clean up vectors */
-    set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
+    /*
+     * Mark vectors up to the cleanup one as used, to prevent an infinite loop
+     * invoking irq_move_cleanup_interrupt.
+     */
+    BUILD_BUG_ON(IRQ_MOVE_CLEANUP_VECTOR < FIRST_DYNAMIC_VECTOR);
+    for ( vector = FIRST_DYNAMIC_VECTOR;
+          vector <= IRQ_MOVE_CLEANUP_VECTOR;
+          vector++ )
+        __set_bit(vector, used_vectors);
 
     return 0;
 }
@@ -734,10 +741,6 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
 {
     unsigned vector, me;
 
-    /* This interrupt should not nest inside others. */
-    BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
-                 APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
-
     ack_APIC_irq();
 
     me = smp_processor_id();
@@ -781,6 +784,11 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
          */
         if ( irr & (1u << (vector % 32)) )
         {
+            if ( vector < IRQ_MOVE_CLEANUP_VECTOR )
+            {
+                ASSERT_UNREACHABLE();
+                goto unlock;
+            }
             send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
             TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY,
                      irq, vector, smp_processor_id());
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55656.96943 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph82-0004XH-Lf; Thu, 17 Dec 2020 00:26:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55656.96943; Thu, 17 Dec 2020 00:26:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph82-0004X9-Il; Thu, 17 Dec 2020 00:26:46 +0000
Received: by outflank-mailman (input) for mailman id 55656;
 Thu, 17 Dec 2020 00:26:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph81-0004Wz-EH
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph81-0003xj-Dd
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph81-0000NE-Cm
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6fqubPeL7DtuctPof9GBYOsWYauSN1PNqD/UOxhMtiE=; b=h1HJWFkCdqhKrgTFH2+xAddnZK
	dugh9wqpB6UtgSDy7HGX8O5KS4CuTvPCbhPi692Wc41hLWAChTIdvK91Iet7nBV7ENVavcCpZhlfX
	ZDzCDf/epofKbxTHJM5stY8ACSEC94D1pkH+UtK9pkHIG4NjcRlHR+96gC0e+D4bh7PI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kph81-0000NE-Cm@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:45 +0000

commit dc8b01affd7f6f36d34c3854f51df0847df3ec0e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:42:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:42:51 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index d508d57219..3310dc00d7 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -55,6 +55,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -605,6 +612,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:26:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:26:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55657.96946 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph8C-0004aj-NF; Thu, 17 Dec 2020 00:26:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55657.96946; Thu, 17 Dec 2020 00:26:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph8C-0004aa-KJ; Thu, 17 Dec 2020 00:26:56 +0000
Received: by outflank-mailman (input) for mailman id 55657;
 Thu, 17 Dec 2020 00:26:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8B-0004aB-HG
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8B-0003yC-GY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8B-0000Nv-Fl
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:26:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dZ90phzyOaC0RCsXFiJ7TYkhQTUcx9S/sVxr9V0PoEw=; b=0YzxRhZq7TdC+YQk/wFamTxuM1
	V4JaK5EBahmnZf1LHZHU3B0rEHLDU8dBXg6/hrVFTukfwbywdUJYz4erLXGN6i3hhb06wcv51aGgI
	XrXkhwSrCsbSjJzh/A9I0hNjzf90YqNsP/HPBF7lBEhmjUD3/uQh5XFWrG9rDFSNCMUA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kph8B-0000Nv-Fl@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:26:55 +0000

commit c5e63651fdc706954d920a2d98f74f4a21b46a7e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:46:37 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:46:37 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 3310dc00d7..2fb01b82db 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -252,6 +252,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
      * Link the event if it unmasked and not already linked.
      */
     if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
+         /*
+          * This also acts as the read counterpart of the smp_wmb() in
+          * map_control_block().
+          */
          !guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
         /*
@@ -478,6 +482,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -488,10 +493,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 00:27:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 00:27:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55659.96951 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph8M-0004c7-Ob; Thu, 17 Dec 2020 00:27:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55659.96951; Thu, 17 Dec 2020 00:27:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kph8M-0004c0-Ll; Thu, 17 Dec 2020 00:27:06 +0000
Received: by outflank-mailman (input) for mailman id 55659;
 Thu, 17 Dec 2020 00:27:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8L-0004bt-Ll
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:27:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8L-0003yZ-Ja
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:27:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kph8L-0000On-Ij
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 00:27:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=c4sp+bqKNSTZOTE2LKqCVxqh2sR9OW0aCqKGDDdt9rw=; b=1BjmMCzputqJ9ldhdEjBJMeweG
	X7UZ0ivQGwqMMeextDa4OSL+IZNszK0kKALYOHy1Grhy+4D3lKqOtr4+byb7sSJtxWOt/QYVzlf/l
	TzPCqcjMGcPhAmIMNFHIaKECec27JAg8HPG2My0pC6XK1HQclJh+6O7FDrP5Bm/y9Ka4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/PV: guest_get_eff_kern_l1e() may still need to switch page tables
Message-Id: <E1kph8L-0000On-Ij@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 00:27:05 +0000

commit 904148ecb4a59d4c8375d8e8d38117b8605e10ac
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 13:47:45 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 13:47:45 2020 +0100

    x86/PV: guest_get_eff_kern_l1e() may still need to switch page tables
    
    While indeed unnecessary for pv_ro_page_fault(), pv_map_ldt_shadow_page()
    may run when guest user mode is active, and hence may need to switch to
    the kernel page tables in order to retrieve an LDT page mapping.
    
    Fixes: 9ff970564764 ("x86/mm: drop guest_get_eff_l1e()")
    Reported-by: Manuel Bouyer <bouyer@antioche.eu.org>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Tested-by: Manuel Bouyer <bouyer@antioche.eu.org>
---
 xen/arch/x86/pv/mm.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/pv/mm.h b/xen/arch/x86/pv/mm.h
index 2a21859dd4..62b1194e87 100644
--- a/xen/arch/x86/pv/mm.h
+++ b/xen/arch/x86/pv/mm.h
@@ -11,10 +11,15 @@ int new_guest_cr3(mfn_t mfn);
  */
 static inline l1_pgentry_t guest_get_eff_kern_l1e(unsigned long linear)
 {
+    struct vcpu *curr = current;
+    bool user_mode = !(curr->arch.flags & TF_kernel_mode);
     l1_pgentry_t l1e;
 
-    ASSERT(!paging_mode_translate(current->domain));
-    ASSERT(!paging_mode_external(current->domain));
+    ASSERT(!paging_mode_translate(curr->domain));
+    ASSERT(!paging_mode_external(curr->domain));
+
+    if ( user_mode )
+        toggle_guest_pt(curr);
 
     if ( unlikely(!__addr_ok(linear)) ||
          __copy_from_user(&l1e,
@@ -22,6 +27,9 @@ static inline l1_pgentry_t guest_get_eff_kern_l1e(unsigned long linear)
                           sizeof(l1_pgentry_t)) )
         l1e = l1e_empty();
 
+    if ( user_mode )
+        toggle_guest_pt(curr);
+
     return l1e;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 02:00:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 02:00:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55687.97006 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpiaM-0004Ci-Ii; Thu, 17 Dec 2020 02:00:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55687.97006; Thu, 17 Dec 2020 02:00:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpiaM-0004CZ-FK; Thu, 17 Dec 2020 02:00:06 +0000
Received: by outflank-mailman (input) for mailman id 55687;
 Thu, 17 Dec 2020 02:00:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpiaL-00045C-Hi
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 02:00:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpiaL-0003kX-Gq
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 02:00:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpiaL-0007Gi-Fc
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 02:00:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=A7TnsQIhEhDMAsRSucLziqziERgFXwjje7VgTaIVgeo=; b=aVzs/pl0TkgWL97AOtkwnQ7kbC
	3DbsbEQP6eT7OGzTajf1i1d596RBmdZy1lLaT91mJOoYUtsIoIC90wpNGaB1yUGk0mcRyJqpjw2cn
	U5YXruzwUwiOjaAB4J71wWlJEc88p+UwMK36Bvpq7h8XOUbaMRrtB/LpCntXwgr5iOEc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/arm: Add workaround for Cortex-A53 erratum #843419
Message-Id: <E1kpiaL-0007Gi-Fc@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 02:00:05 +0000

commit d81133d45d81d35a4e7445778bfd1179190cbd31
Author:     Luca Fancellu <luca.fancellu@arm.com>
AuthorDate: Thu Dec 10 10:42:58 2020 +0000
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Wed Dec 16 17:56:33 2020 -0800

    xen/arm: Add workaround for Cortex-A53 erratum #843419
    
    On the Cortex A53, when executing in AArch64 state, a load or store instruction
    which uses the result of an ADRP instruction as a base register, or which uses
    a base register written by an instruction immediately after an ADRP to the
    same register, might access an incorrect address.
    
    The workaround is to enable the linker flag --fix-cortex-a53-843419
    if present, to check and fix the affected sequence. Otherwise print a warning
    that Xen may be susceptible to this errata
    
    Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
 docs/misc/arm/silicon-errata.txt |  1 +
 xen/arch/arm/Kconfig             | 19 +++++++++++++++++++
 xen/arch/arm/Makefile            |  8 ++++++++
 xen/scripts/Kbuild.include       | 12 ++++++++++++
 4 files changed, 40 insertions(+)

diff --git a/docs/misc/arm/silicon-errata.txt b/docs/misc/arm/silicon-errata.txt
index 27bf957ebf..1925d8fd4e 100644
--- a/docs/misc/arm/silicon-errata.txt
+++ b/docs/misc/arm/silicon-errata.txt
@@ -45,6 +45,7 @@ stable hypervisors.
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319    |
 | ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069    |
 | ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472    |
+| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419    |
 | ARM            | Cortex-A55      | #1530923        | N/A                     |
 | ARM            | Cortex-A57      | #852523         | N/A                     |
 | ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075    |
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index f5b1bcda03..41bde2f401 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -186,6 +186,25 @@ config ARM64_ERRATUM_819472
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_843419
+	bool "Cortex-A53: 843419: A load or store might access an incorrect address"
+	default y
+	depends on ARM_64
+	help
+	  This option adds an alternative code sequence to work around ARM
+	  erratum 843419 on Cortex-A53 parts up to r0p4.
+
+	  When executing in AArch64 state, a load or store instruction which uses
+	  the result of an ADRP instruction as a base register, or which uses a
+	  base register written by an instruction immediately after an ADRP to the
+	  same register, might access an incorrect address.
+
+	  The workaround enables the linker to check if the affected sequence is
+	  produced and it will fix it with an alternative not affected sequence
+	  that produce the same behavior.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_832075
 	bool "Cortex-A57: 832075: possible deadlock on mixing exclusive memory accesses with device loads"
 	default y
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 296c5e68bb..ad2d497c45 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -101,6 +101,14 @@ prelink.o: $(ALL_OBJS) FORCE
 	$(call if_changed,ld)
 endif
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
+    ifeq ($(call ld-option, --fix-cortex-a53-843419),n)
+        $(warning ld does not support --fix-cortex-a53-843419; xen may be susceptible to erratum)
+    else
+        XEN_LDFLAGS += --fix-cortex-a53-843419
+    endif
+endif
+
 targets += prelink.o
 
 $(TARGET)-syms: prelink.o xen.lds
diff --git a/xen/scripts/Kbuild.include b/xen/scripts/Kbuild.include
index e62eddc365..83c7e1457b 100644
--- a/xen/scripts/Kbuild.include
+++ b/xen/scripts/Kbuild.include
@@ -43,6 +43,18 @@ define as-option-add-closure
     endif
 endef
 
+# $(if-success,<command>,<then>,<else>)
+# Return <then> if <command> exits with 0, <else> otherwise.
+if-success = $(shell { $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
+
+# $(success,<command>)
+# Return y if <command> exits with 0, n otherwise
+success = $(call if-success,$(1),y,n)
+
+# $(ld-option,<flag>)
+# Return y if the linker supports <flag>, n otherwise
+ld-option = $(call success,$(LD) -v $(1))
+
 # cc-ifversion
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
 cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4))
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:22:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:22:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55960.97612 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6T-0001y1-Nw; Thu, 17 Dec 2020 15:22:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55960.97612; Thu, 17 Dec 2020 15:22:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6T-0001xt-L2; Thu, 17 Dec 2020 15:22:05 +0000
Received: by outflank-mailman (input) for mailman id 55960;
 Thu, 17 Dec 2020 15:22:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6S-0001xm-R7
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6S-0001T1-Pi
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6S-0006M7-OJ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=3+axUHqbG61jps4PTUgO+1V/icZj+Jo6dDQBbkP6A1Y=; b=F5dw/jSS4jYgceR/NL+I5Juehv
	UgM8zjesh4IX9rKyZyTl5ZFL8arAKfEYVUZPRFXVV0RFL6GzxcfkSsPVJq/Uf5Nnf3zW3MtlmiSXm
	lKKxfIy/ztbabIXYP1fjrfiqauZ4wIXSqKm2qdpaXky5iX8Mu1sS9q26F2yJVZlIqIec=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: switch barf[_perror]() to use syslog()
Message-Id: <E1kpv6S-0006M7-OJ@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:22:04 +0000

commit cbc86340ac75c8ff50e51a16c8fdbdf3d2a7c55d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:39 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: switch barf[_perror]() to use syslog()
    
    When xenstored crashes due to an unrecoverable condition it is calling
    either barf() or barf_perror() to issue a message and then exit().
    
    Make sure the message is visible somewhere by using syslog()
    additionally to xprintf(), as the latter will be visible only with
    tracing active.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/utils.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/xenstore/utils.c b/tools/xenstore/utils.c
index a1ac12584a..633ce3b4fc 100644
--- a/tools/xenstore/utils.c
+++ b/tools/xenstore/utils.c
@@ -3,6 +3,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -35,6 +36,7 @@ void barf(const char *fmt, ...)
 	va_end(arglist);
 
  	if (bytes >= 0) {
+		syslog(LOG_CRIT, "%s\n", str);
 		xprintf("%s\n", str);
 		free(str);
 	}
@@ -54,6 +56,7 @@ void barf_perror(const char *fmt, ...)
 	va_end(arglist);
 
  	if (bytes >= 0) {
+		syslog(LOG_CRIT, "%s: %s\n", str, strerror(err));
 		xprintf("%s: %s\n", str, strerror(err));
 		free(str);
 	}
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:22:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:22:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55961.97617 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6e-0001yn-PU; Thu, 17 Dec 2020 15:22:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55961.97617; Thu, 17 Dec 2020 15:22:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6e-0001yf-MY; Thu, 17 Dec 2020 15:22:16 +0000
Received: by outflank-mailman (input) for mailman id 55961;
 Thu, 17 Dec 2020 15:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6c-0001yZ-Vw
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6c-0001T4-Tx
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6c-0006NL-S5
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=HcFxQaHEgrdTwB1ply6pPjbHplaTMpDArWlSKBU2y+I=; b=zRCtxCv6sDAAZb8j1QoZA7Skmx
	bj84KjAWmfDtl95LItvXO0Ai3mF56Fmi+BnRI7pRJrRgtQlNUpTw9WYRRXjh1knm4PXVmxhaCjnJ4
	/OY69KZ2Y8Vyz+6y9LC4oKBONz6zTH2ajwBMQ3PZEwp+pgW2I7YH9lD+I1C0kLvlC4K0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: make set_tdb_key() non-static
Message-Id: <E1kpv6c-0006NL-S5@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:22:14 +0000

commit 2474e53726bda64fac9d604fbc2128df88b54cfb
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:40 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: make set_tdb_key() non-static
    
    set_tdb_key() can be used by destroy_node(), too. So remove the static
    attribute and move it to xenstored_core.c.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 14 +++++++++++---
 tools/xenstore/xenstored_core.h        |  2 ++
 tools/xenstore/xenstored_transaction.c |  6 ------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3082a36d3a..ab1c7835b8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -352,6 +352,16 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
 	}
 }
 
+void set_tdb_key(const char *name, TDB_DATA *key)
+{
+	/*
+	 * Dropping const is fine here, as the key will never be modified
+	 * by TDB.
+	 */
+	key->dptr = (char *)name;
+	key->dsize = strlen(name);
+}
+
 /*
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
@@ -985,9 +995,7 @@ static int destroy_node(void *_node)
 	if (streq(node->name, "/"))
 		corrupt(NULL, "Destroying root node!");
 
-	key.dptr = (void *)node->name;
-	key.dsize = strlen(node->name);
-
+	set_tdb_key(node->name, &key);
 	tdb_delete(tdb_ctx, key);
 
 	domain_entry_dec(talloc_parent(node), node);
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 4c6c3d6f20..fb59d862a2 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -220,6 +220,8 @@ extern xengnttab_handle **xgt_handle;
 
 int remember_string(struct hashtable *hash, const char *str);
 
+void set_tdb_key(const char *name, TDB_DATA *key);
+
 #endif /* _XENSTORED_CORE_H */
 
 /*
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2881f3b2e4..52355f4ed8 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -168,12 +168,6 @@ struct transaction
 extern int quota_max_transaction;
 uint64_t generation;
 
-static void set_tdb_key(const char *name, TDB_DATA *key)
-{
-	key->dptr = (char *)name;
-	key->dsize = strlen(name);
-}
-
 static struct accessed_node *find_accessed_node(struct transaction *trans,
 						const char *name)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:22:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:22:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.55963.97621 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6o-00020J-RR; Thu, 17 Dec 2020 15:22:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 55963.97621; Thu, 17 Dec 2020 15:22:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpv6o-00020B-OM; Thu, 17 Dec 2020 15:22:26 +0000
Received: by outflank-mailman (input) for mailman id 55963;
 Thu, 17 Dec 2020 15:22:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6n-0001zu-3B
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6n-0001TC-2L
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpv6n-0006O4-0B
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:22:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6prYuWjTFEitzjDtI3wz6oSdUT8Sd8n48yDv8PnZ5ak=; b=ENRViumptA3RNpa0psoKlfzRAk
	af+hronJipo2/gRnsC1WhSB3bFIozaG1jn7xKPlzxoFdRIbZDk5KKws86qv7Tk99WojUPsKSz5oS+
	kv+8ar2febmqTjVk9cWk+s9BgOWo7W/pEFTFPb6ET9Xno/w3Nlej6EOK7YIE7tos34KE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] tools/xenstore: remove unused cruft from xenstored_domain.c
Message-Id: <E1kpv6n-0006O4-0B@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:22:25 +0000

commit fe733fa0998e280b400904aaf9f624c67a311414
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:41 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: remove unused cruft from xenstored_domain.c
    
    domain->remote_port and restore_existing_connections() are useless and
    can be removed.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c   |  3 ---
 tools/xenstore/xenstored_domain.c | 11 -----------
 tools/xenstore/xenstored_domain.h |  3 ---
 3 files changed, 17 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ab1c7835b8..50986f8b29 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -2087,9 +2087,6 @@ int main(int argc, char *argv[])
 	if (!no_domain_init)
 		domain_init();
 
-	/* Restore existing connections. */
-	restore_existing_connections();
-
 	if (outputpid) {
 		printf("%ld\n", (long)getpid());
 		fflush(stdout);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7d348d57f3..ed8e83b06b 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -54,10 +54,6 @@ struct domain
 	/* Event channel port */
 	evtchn_port_t port;
 
-	/* The remote end of the event channel, used only to validate
-	   repeated domain introductions. */
-	evtchn_port_t remote_port;
-
 	/* Domain path in store. */
 	char *path;
 
@@ -382,7 +378,6 @@ static int new_domain(struct domain *domain, int port)
 	domain->conn->domain = domain;
 	domain->conn->id = domain->domid;
 
-	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
@@ -470,7 +465,6 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 			xenevtchn_unbind(xce_handle, domain->port);
 		rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
 		domain->port = (rc == -1) ? 0 : rc;
-		domain->remote_port = port;
 	}
 
 	domain_conn_reset(domain);
@@ -636,11 +630,6 @@ const char *get_implicit_path(const struct connection *conn)
 	return conn->domain->path;
 }
 
-/* Restore existing connections. */
-void restore_existing_connections(void)
-{
-}
-
 static int set_dom_perms_default(struct node_perms *perms)
 {
 	perms->num = 1;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 5e00087206..66e0a12654 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -47,9 +47,6 @@ void domain_init(void);
 /* Returns the implicit path of a connection (only domains have this) */
 const char *get_implicit_path(const struct connection *conn);
 
-/* Read existing connection information from store. */
-void restore_existing_connections(void);
-
 /* Can connection attached to domain read/write. */
 bool domain_can_read(struct connection *conn);
 bool domain_can_write(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:55:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:55:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56032.97775 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvcQ-0006Gp-Nb; Thu, 17 Dec 2020 15:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56032.97775; Thu, 17 Dec 2020 15:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvcQ-0006Gh-Kh; Thu, 17 Dec 2020 15:55:06 +0000
Received: by outflank-mailman (input) for mailman id 56032;
 Thu, 17 Dec 2020 15:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcO-0006Ga-Uk
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcO-00020b-S7
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcO-0001Ca-Qv
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=UYA+XrFpP947K/oxMdVInjeboREHZbZo97dSmnd8byE=; b=IWYrRktbwgWqrwUdM3rq9plqSX
	4iXIVKW96qQn/KoTSvCgt3lKClCFxYv6Luxrl6L97jRkOCfWcrQUNQrApzmiLoBr5icZyi+Z4wNXC
	LMs6CWgq7nEwwtOx3qBbZUcCX+7syHcpNTi9iLVTqzfwHv7odsr8ONh/Tt6TVc5rEfzE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/cpupool: support moving domain between cpupools with different granularity
Message-Id: <E1kpvcO-0001Ca-Qv@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:55:04 +0000

commit 70fadc41635b9b620de63f83cdf578d7ccf00a2b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:49:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:49:11 2020 +0100

    xen/cpupool: support moving domain between cpupools with different granularity
    
    When moving a domain between cpupools with different scheduling
    granularity the sched_units of the domain need to be adjusted.
    
    Do that by allocating new sched_units and throwing away the old ones
    in sched_move_domain().
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c | 120 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 89 insertions(+), 31 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index a429fc7640..9745a77eee 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -613,17 +613,45 @@ static void sched_move_irqs(const struct sched_unit *unit)
         vcpu_move_irqs(v);
 }
 
+/*
+ * Move a domain from one cpupool to another.
+ *
+ * A domain with any vcpu having temporary affinity settings will be denied
+ * to move. Hard and soft affinities will be reset.
+ *
+ * In order to support cpupools with different scheduling granularities all
+ * scheduling units are replaced by new ones.
+ *
+ * The complete move is done in the following steps:
+ * - check prerequisites (no vcpu with temporary affinities)
+ * - allocate all new data structures (scheduler specific domain data, unit
+ *   memory, scheduler specific unit data)
+ * - pause domain
+ * - temporarily move all (old) units to the same scheduling resource (this
+ *   makes the final resource assignment easier in case the new cpupool has
+ *   a larger granularity than the old one, as the scheduling locks for all
+ *   vcpus must be held for that operation)
+ * - remove old units from scheduling
+ * - set new cpupool and scheduler domain data pointers in struct domain
+ * - switch all vcpus to new units, still assigned to the old scheduling
+ *   resource
+ * - migrate all new units to scheduling resources of the new cpupool
+ * - unpause the domain
+ * - free the old memory (scheduler specific domain data, unit memory,
+ *   scheduler specific unit data)
+ */
 int sched_move_domain(struct domain *d, struct cpupool *c)
 {
     struct vcpu *v;
-    struct sched_unit *unit;
+    struct sched_unit *unit, *old_unit;
+    struct sched_unit *new_units = NULL, *old_units;
+    struct sched_unit **unit_ptr = &new_units;
     unsigned int new_p, unit_idx;
-    void **unit_priv;
     void *domdata;
-    void *unitdata;
-    struct scheduler *old_ops;
+    struct scheduler *old_ops = dom_scheduler(d);
     void *old_domdata;
     unsigned int gran = cpupool_get_granularity(c);
+    unsigned int n_units = DIV_ROUND_UP(d->max_vcpus, gran);
     int ret = 0;
 
     for_each_vcpu ( d, v )
@@ -641,53 +669,77 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
         goto out;
     }
 
-    unit_priv = xzalloc_array(void *, DIV_ROUND_UP(d->max_vcpus, gran));
-    if ( unit_priv == NULL )
+    for ( unit_idx = 0; unit_idx < n_units; unit_idx++ )
     {
-        sched_free_domdata(c->sched, domdata);
-        ret = -ENOMEM;
-        goto out;
-    }
+        unit = sched_alloc_unit_mem();
+        if ( unit )
+        {
+            /* Initialize unit for sched_alloc_udata() to work. */
+            unit->domain = d;
+            unit->unit_id = unit_idx * gran;
+            unit->vcpu_list = d->vcpu[unit->unit_id];
+            unit->priv = sched_alloc_udata(c->sched, unit, domdata);
+            *unit_ptr = unit;
+        }
 
-    unit_idx = 0;
-    for_each_sched_unit ( d, unit )
-    {
-        unit_priv[unit_idx] = sched_alloc_udata(c->sched, unit, domdata);
-        if ( unit_priv[unit_idx] == NULL )
+        if ( !unit || !unit->priv )
         {
-            for ( unit_idx = 0; unit_priv[unit_idx]; unit_idx++ )
-                sched_free_udata(c->sched, unit_priv[unit_idx]);
-            xfree(unit_priv);
-            sched_free_domdata(c->sched, domdata);
+            old_units = new_units;
+            old_domdata = domdata;
             ret = -ENOMEM;
-            goto out;
+            goto out_free;
         }
-        unit_idx++;
+
+        unit_ptr = &unit->next_in_list;
     }
 
     domain_pause(d);
 
-    old_ops = dom_scheduler(d);
     old_domdata = d->sched_priv;
 
+    /*
+     * Temporarily move all units to same processor to make locking
+     * easier when moving the new units to the new processors.
+     */
+    new_p = cpumask_first(d->cpupool->cpu_valid);
     for_each_sched_unit ( d, unit )
     {
+        spinlock_t *lock = unit_schedule_lock_irq(unit);
+
+        sched_set_res(unit, get_sched_res(new_p));
+        spin_unlock_irq(lock);
+
         sched_remove_unit(old_ops, unit);
     }
 
+    old_units = d->sched_unit_list;
+
     d->cpupool = c;
     d->sched_priv = domdata;
 
+    unit = new_units;
+    for_each_vcpu ( d, v )
+    {
+        old_unit = v->sched_unit;
+        if ( unit->unit_id + gran == v->vcpu_id )
+            unit = unit->next_in_list;
+
+        unit->state_entry_time = old_unit->state_entry_time;
+        unit->runstate_cnt[v->runstate.state]++;
+        /* Temporarily use old resource assignment */
+        unit->res = get_sched_res(new_p);
+
+        v->sched_unit = unit;
+    }
+
+    d->sched_unit_list = new_units;
+
     new_p = cpumask_first(c->cpu_valid);
-    unit_idx = 0;
     for_each_sched_unit ( d, unit )
     {
         spinlock_t *lock;
         unsigned int unit_p = new_p;
 
-        unitdata = unit->priv;
-        unit->priv = unit_priv[unit_idx];
-
         for_each_sched_unit_vcpu ( unit, v )
         {
             migrate_timer(&v->periodic_timer, new_p);
@@ -713,8 +765,6 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
 
         sched_insert_unit(c->sched, unit);
 
-        sched_free_udata(old_ops, unitdata);
-
         unit_idx++;
     }
 
@@ -722,11 +772,19 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
 
     domain_unpause(d);
 
-    sched_free_domdata(old_ops, old_domdata);
+ out_free:
+    for ( unit = old_units; unit; )
+    {
+        if ( unit->priv )
+            sched_free_udata(c->sched, unit->priv);
+        old_unit = unit;
+        unit = unit->next_in_list;
+        xfree(old_unit);
+    }
 
-    xfree(unit_priv);
+    sched_free_domdata(old_ops, old_domdata);
 
-out:
+ out:
     rcu_read_unlock(&sched_res_rculock);
 
     return ret;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:55:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:55:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56033.97778 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvcZ-0006Hv-PI; Thu, 17 Dec 2020 15:55:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56033.97778; Thu, 17 Dec 2020 15:55:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvcZ-0006Hn-MG; Thu, 17 Dec 2020 15:55:15 +0000
Received: by outflank-mailman (input) for mailman id 56033;
 Thu, 17 Dec 2020 15:55:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcY-0006Hd-W6
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcY-00020k-VO
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcY-0001Dg-UF
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fUeb8sfEyceusqyOg4psgeQgv3IreFzbVylDSI9eaDE=; b=6sjl+5VJsWq9VLMMzmZAeDwgaZ
	gAB/WfYA7bT4lt1+QkP3uL1YnnRKsP+J8vm1tBm7uzq2rzmD/kndv+fwuBSRnmkGqfJ04U4NvkkDO
	K7Vm0VbWlW1XjycYqBoeKQFDGlc9PxVBGZ72bpCfGpJQ/uQFmbh2jnRYTbj81eeEK+EQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/hypfs: switch write function handles to const
Message-Id: <E1kpvcY-0001Dg-UF@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:55:14 +0000

commit fbb2b92de0782b4ea183377e014d941fbec0bab7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:49:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:49:49 2020 +0100

    xen/hypfs: switch write function handles to const
    
    The node specific write functions take a void user address handle as
    parameter. As a write won't change the user memory use a const_void
    handle instead.
    
    This requires a new macro for casting a guest handle to a const type.
    
    Suggested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c             | 17 +++++++++++------
 xen/include/xen/guest_access.h |  5 +++++
 xen/include/xen/hypfs.h        | 14 +++++++++-----
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 2e8e90591e..6f822ae097 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -344,7 +344,8 @@ static int hypfs_read(const struct hypfs_entry *entry,
 }
 
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     char *buf;
     int ret;
@@ -384,7 +385,8 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     bool buf;
 
@@ -405,7 +407,8 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned int ulen)
 {
     struct param_hypfs *p;
     char *buf;
@@ -439,13 +442,15 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     return -EACCES;
 }
 
 static int hypfs_write(struct hypfs_entry *entry,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned long ulen)
 {
     struct hypfs_entry_leaf *l;
 
@@ -497,7 +502,7 @@ long do_hypfs_op(unsigned int cmd,
         break;
 
     case XEN_HYPFS_OP_write_contents:
-        ret = hypfs_write(entry, arg3, arg4);
+        ret = hypfs_write(entry, guest_handle_const_cast(arg3, void), arg4);
         break;
 
     default:
diff --git a/xen/include/xen/guest_access.h b/xen/include/xen/guest_access.h
index f9b94cf1f4..af33ae3ab6 100644
--- a/xen/include/xen/guest_access.h
+++ b/xen/include/xen/guest_access.h
@@ -26,6 +26,11 @@
     type *_x = (hnd).p;                         \
     (XEN_GUEST_HANDLE_PARAM(type)) { _x };      \
 })
+/* Same for casting to a const type. */
+#define guest_handle_const_cast(hnd, type) ({      \
+    const type *p_ = (hnd).p;                      \
+    (XEN_GUEST_HANDLE_PARAM(const_##type)) { p_ }; \
+})
 
 /* Cast a XEN_GUEST_HANDLE to XEN_GUEST_HANDLE_PARAM */
 #define guest_handle_to_param(hnd, type) ({                  \
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 53f50772b4..99fd4b036d 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -38,7 +38,7 @@ struct hypfs_funcs {
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
-                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                 XEN_GUEST_HANDLE_PARAM(const_void) uaddr, unsigned int ulen);
     unsigned int (*getsize)(const struct hypfs_entry *entry);
     struct hypfs_entry *(*findentry)(const struct hypfs_entry_dir *dir,
                                      const char *name, unsigned int name_len);
@@ -154,13 +154,17 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
 int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned int ulen);
 unsigned int hypfs_getsize(const struct hypfs_entry *entry);
 struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
                                          const char *name,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 15:55:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 15:55:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56034.97784 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvck-0006Jd-Rw; Thu, 17 Dec 2020 15:55:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56034.97784; Thu, 17 Dec 2020 15:55:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpvck-0006JV-Ns; Thu, 17 Dec 2020 15:55:26 +0000
Received: by outflank-mailman (input) for mailman id 56034;
 Thu, 17 Dec 2020 15:55:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcj-0006JJ-3g
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcj-00020u-2o
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpvcj-0001En-1c
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 15:55:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=S+327+XjFduHiZlrmdUgnJalxCosdi88cXzsPw7jPgQ=; b=Ufw6STpXCJj3NzLpFwJLCwT6V2
	0mZsc46gRNxuNi2g3O0q5YAOq6JWhnejGX2JRrPo+2JcggXyBV/Pq66CAFCCNthONC3wHIipmEWS4
	x6K2zsV6+79c+qBY69Fedlvea+RYQ0Y4fcuxYLL1WhiC+w6TDDu0cCJV+sIIABoEuXYA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/hypfs: add new enter() and exit() per node callbacks
Message-Id: <E1kpvcj-0001En-1c@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 15:55:25 +0000

commit 641723f78d3a0b1982e1cd2ef37d8d877cfe542d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:50:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:50:21 2020 +0100

    xen/hypfs: add new enter() and exit() per node callbacks
    
    In order to better support resource allocation and locking for dynamic
    hypfs nodes add enter() and exit() callbacks to struct hypfs_funcs.
    
    The enter() callback is called when entering a node during hypfs user
    actions (traversing, reading or writing it), while the exit() callback
    is called when leaving a node (accessing another node at the same or a
    higher directory level, or when returning to the user).
    
    For avoiding recursion this requires a parent pointer in each node.
    Let the enter() callback return the entry address which is stored as
    the last accessed node in order to be able to use a template entry for
    that purpose in case of dynamic entries.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c      | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/hypfs.h |  5 ++++
 2 files changed, 82 insertions(+)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 6f822ae097..73497ea1d7 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -25,30 +25,40 @@ CHECK_hypfs_dirlistentry;
      ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
 
 const struct hypfs_funcs hypfs_dir_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_dir,
     .write = hypfs_write_deny,
     .getsize = hypfs_getsize,
     .findentry = hypfs_dir_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_ro_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_deny,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_leaf,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_bool_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_bool,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_custom_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_custom,
     .getsize = hypfs_getsize,
@@ -63,6 +73,8 @@ enum hypfs_lock_state {
 };
 static DEFINE_PER_CPU(enum hypfs_lock_state, hypfs_locked);
 
+static DEFINE_PER_CPU(const struct hypfs_entry *, hypfs_last_node_entered);
+
 HYPFS_DIR_INIT(hypfs_root, "");
 
 static void hypfs_read_lock(void)
@@ -100,11 +112,56 @@ static void hypfs_unlock(void)
     }
 }
 
+const struct hypfs_entry *hypfs_node_enter(const struct hypfs_entry *entry)
+{
+    return entry;
+}
+
+void hypfs_node_exit(const struct hypfs_entry *entry)
+{
+}
+
+static int node_enter(const struct hypfs_entry *entry)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    entry = entry->funcs->enter(entry);
+    if ( IS_ERR(entry) )
+        return PTR_ERR(entry);
+
+    ASSERT(entry);
+    ASSERT(!*last || *last == entry->parent);
+
+    *last = entry;
+
+    return 0;
+}
+
+static void node_exit(const struct hypfs_entry *entry)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    ASSERT(*last == entry);
+    *last = entry->parent;
+
+    entry->funcs->exit(entry);
+}
+
+static void node_exit_all(void)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    while ( *last )
+        node_exit(*last);
+}
+
 static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
 {
     int ret = -ENOENT;
     struct hypfs_entry *e;
 
+    ASSERT(new->funcs->enter);
+    ASSERT(new->funcs->exit);
     ASSERT(new->funcs->read);
     ASSERT(new->funcs->write);
     ASSERT(new->funcs->getsize);
@@ -140,6 +197,7 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
         unsigned int sz = strlen(new->name);
 
         parent->e.size += DIRENTRY_SIZE(sz);
+        new->parent = &parent->e;
     }
 
     hypfs_unlock();
@@ -221,6 +279,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
     const char *end;
     struct hypfs_entry *entry;
     unsigned int name_len;
+    int ret;
 
     for ( ; ; )
     {
@@ -235,6 +294,10 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
             end = strchr(path, '\0');
         name_len = end - path;
 
+        ret = node_enter(&dir->e);
+        if ( ret )
+            return ERR_PTR(ret);
+
         entry = dir->e.funcs->findentry(dir, path, name_len);
         if ( IS_ERR(entry) || !*end )
             return entry;
@@ -265,6 +328,7 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
     const struct hypfs_entry_dir *d;
     const struct hypfs_entry *e;
     unsigned int size = entry->funcs->getsize(entry);
+    int ret;
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
@@ -276,12 +340,19 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
         unsigned int e_namelen = strlen(e->name);
         unsigned int e_len = DIRENTRY_SIZE(e_namelen);
 
+        ret = node_enter(e);
+        if ( ret )
+            return ret;
+
         direntry.e.pad = 0;
         direntry.e.type = e->type;
         direntry.e.encoding = e->encoding;
         direntry.e.content_len = e->funcs->getsize(e);
         direntry.e.max_write_len = e->max_size;
         direntry.off_next = list_is_last(&e->list, &d->dirlist) ? 0 : e_len;
+
+        node_exit(e);
+
         if ( copy_to_guest(uaddr, &direntry, 1) )
             return -EFAULT;
 
@@ -495,6 +566,10 @@ long do_hypfs_op(unsigned int cmd,
         goto out;
     }
 
+    ret = node_enter(entry);
+    if ( ret )
+        goto out;
+
     switch ( cmd )
     {
     case XEN_HYPFS_OP_read:
@@ -511,6 +586,8 @@ long do_hypfs_op(unsigned int cmd,
     }
 
  out:
+    node_exit_all();
+
     hypfs_unlock();
 
     return ret;
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 99fd4b036d..a6dfdb7d8e 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -35,6 +35,8 @@ struct hypfs_entry;
  * "/a/b/c" findentry() will be called for "/", "/a", and "/a/b").
  */
 struct hypfs_funcs {
+    const struct hypfs_entry *(*enter)(const struct hypfs_entry *entry);
+    void (*exit)(const struct hypfs_entry *entry);
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
@@ -56,6 +58,7 @@ struct hypfs_entry {
     unsigned int size;
     unsigned int max_size;
     const char *name;
+    struct hypfs_entry *parent;
     struct list_head list;
     const struct hypfs_funcs *funcs;
 };
@@ -149,6 +152,8 @@ int hypfs_add_dir(struct hypfs_entry_dir *parent,
                   struct hypfs_entry_dir *dir, bool nofault);
 int hypfs_add_leaf(struct hypfs_entry_dir *parent,
                    struct hypfs_entry_leaf *leaf, bool nofault);
+const struct hypfs_entry *hypfs_node_enter(const struct hypfs_entry *entry);
+void hypfs_node_exit(const struct hypfs_entry *entry);
 int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_read_leaf(const struct hypfs_entry *entry,
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 16:55:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 16:55:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56065.97862 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpwYU-0004sg-Ab; Thu, 17 Dec 2020 16:55:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56065.97862; Thu, 17 Dec 2020 16:55:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kpwYU-0004sY-7Z; Thu, 17 Dec 2020 16:55:06 +0000
Received: by outflank-mailman (input) for mailman id 56065;
 Thu, 17 Dec 2020 16:55:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpwYS-0004sT-Uz
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 16:55:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpwYS-0003Z8-SO
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 16:55:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kpwYS-0001aK-RR
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 16:55:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AYcaeWIGhiOLbaAHENfEu5Lz46AWqxP+Y+/HLNaxkHQ=; b=gRLZ8f7ciPSFVcQ9zi+wEKu3rA
	bgiXmWGLnX1Fy3gdfB8cPUX/57vUdvPyLinoGrDtgZpAzVqyQ411FAnf7RuSj4+YfIBW3WYUWoBMa
	ZqzyLs2WXMR/+B1kwWD5rnvbBXH5DaOZn5xms5PjxTeFyqn//V8ulS2w0tqcWYIvP/h0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging-4.14] update Xen version to 4.14.1
Message-Id: <E1kpwYS-0001aK-RR@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 16:55:04 +0000

commit ad844aa352559a8b1f36e391a27d9d7dbddbdc36
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Thu Dec 17 17:47:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 17:47:25 2020 +0100

    update Xen version to 4.14.1
---
 Config.mk    | 6 +++---
 xen/Makefile | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Config.mk b/Config.mk
index 264dc0d27d..bc4ee6fe34 100644
--- a/Config.mk
+++ b/Config.mk
@@ -245,15 +245,15 @@ SEABIOS_UPSTREAM_URL ?= git://xenbits.xen.org/seabios.git
 MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
 endif
 OVMF_UPSTREAM_REVISION ?= 20d2e5a125e34fc8501026613a71549b2a1a3e54
-QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.0
-MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.0
+QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.1
+MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.1
 
 SEABIOS_UPSTREAM_REVISION ?= rel-1.13.0
 
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= xen-4.14.0
+QEMU_TRADITIONAL_REVISION ?= xen-4.14.1
 
 # Specify which qemu-dm to use. This may be `ioemu' to use the old
 # Mercurial in-tree version, or a local directory, or a git URL.
diff --git a/xen/Makefile b/xen/Makefile
index 110ea0f1a8..df7cf10be3 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 14
-export XEN_EXTRAVERSION ?= .1-pre$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .1$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.14


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56145.98025 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0NY-0004be-Dd; Thu, 17 Dec 2020 21:00:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56145.98025; Thu, 17 Dec 2020 21:00:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0NY-0004bI-AB; Thu, 17 Dec 2020 21:00:04 +0000
Received: by outflank-mailman (input) for mailman id 56145;
 Thu, 17 Dec 2020 21:00:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0NW-0004SH-Ly
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0NW-0007pB-Il
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0NW-00060l-Gr
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yJydH3h5+q+k+L7XteMowO/MLRynDXJ/lbeNPCPxZX4=; b=ZjAWXWCs931h95C/z9exJ+z/vz
	4MT37gB0UFNI2av3Hvnm6vJ+napfAvUTRjFWfvgXWJVa5juoHbGBJAmaki0jgWFDc34SI/5QCUl7e
	SEHcm0WUE2VNSmTrsa6s2+gzfdm/IqRSkEITAjQy5HHfc7HboYOBwI0fb9l8QHl4EuV8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] examples: Add PVH example to config example list
Message-Id: <E1kq0NW-00060l-Gr@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:02 +0000

commit 3e6944bf18461e3919ade89f11bcd735e8f992ec
Author:     Elliott Mitchell <ehem+xen@m5p.com>
AuthorDate: Mon Dec 14 18:35:32 2020 -0800
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:51:58 2020 +0000

    examples: Add PVH example to config example list
    
    Somewhat helpful to actually install the example configurations.
    
    Signed-off-by: Elliott Mitchell <ehem+xen@m5p.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/examples/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/examples/Makefile b/tools/examples/Makefile
index 2a6c5444d4..14e24f4cb3 100644
--- a/tools/examples/Makefile
+++ b/tools/examples/Makefile
@@ -6,6 +6,7 @@ XEN_READMES = README
 
 XEN_CONFIGS += xlexample.hvm
 XEN_CONFIGS += xlexample.pvlinux
+XEN_CONFIGS += xlexample.pvhlinux
 XEN_CONFIGS += xl.conf
 XEN_CONFIGS += cpupool
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56146.98029 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Ni-00050i-Ek; Thu, 17 Dec 2020 21:00:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56146.98029; Thu, 17 Dec 2020 21:00:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Ni-00050Y-Bf; Thu, 17 Dec 2020 21:00:14 +0000
Received: by outflank-mailman (input) for mailman id 56146;
 Thu, 17 Dec 2020 21:00:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Ng-00050I-NC
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Ng-0007pa-MJ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Ng-00062W-Ky
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=icBzu7gmZ5x6J3zbo8F8Afoa6BIFuU9TBi2ceXHn9n0=; b=o/K+Tlckcjk+kn84w6kKwtrICl
	ozDwcB3dt8z/aUYCdqf5/SobtN6UepW3KPQrJbPdAN6QGN0SU826ku4Yd4PIwuwuAUgSqy0WoIkVh
	zvJ+7kZrIAS7uDHPC3wCgXO/wSN0aexK1gv225o1ur3llPeEGHpo1LqVlWn9GCWPMsbY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] MAINTAINERS: add me as maintainer for tools/xenstore/
Message-Id: <E1kq0Ng-00062W-Ky@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:12 +0000

commit c6dc730e52abfba9cea4ccbfead1c494707bca57
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 8 11:30:26 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:54:44 2020 +0000

    MAINTAINERS: add me as maintainer for tools/xenstore/
    
    I have been the major contributor for C Xenstore the past few years.
    
    Add me as a maintainer for tools/xenstore/.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dab38a6a14..6dbd99aff4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -584,6 +584,13 @@ F:	xen/include/asm-x86/guest/hyperv-hcall.h
 F:	xen/include/asm-x86/guest/hyperv-tlfs.h
 F:	xen/include/asm-x86/hvm/viridian.h
 
+XENSTORE
+M:	Ian Jackson <iwj@xenproject.org>
+M:	Wei Liu <wl@xen.org>
+M:	Juergen Gross <jgross@suse.com>
+S:	Supported
+F:	tools/xenstore/
+
 XENTRACE
 M:	George Dunlap <george.dunlap@citrix.com>
 S:	Supported
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56147.98033 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Ns-00051v-Gr; Thu, 17 Dec 2020 21:00:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56147.98033; Thu, 17 Dec 2020 21:00:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Ns-00051n-D6; Thu, 17 Dec 2020 21:00:24 +0000
Received: by outflank-mailman (input) for mailman id 56147;
 Thu, 17 Dec 2020 21:00:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Nq-00051c-RR
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Nq-0007pl-Qe
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Nq-00063t-OV
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yqBYLLJfPq15tpS9RUBU0oApr7oX2WS1poqAxRwjZGQ=; b=HUlq5GQq1otT8xvfuLSj1iji8v
	lYjV4W2VkHflHC3Y3FPg0qJ6dL/vrc9x8zLvfenGoLByXN+01ppC9oRfSmofKSe+sHyTMPbSRk0Dr
	pseW72wm/T+nPgEsAd5aFsrVOGWUiqi4x+vCxlFHxBvM0ObXgdO8p1jmXIOTFN3MrkEQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: rework path length check
Message-Id: <E1kq0Nq-00063t-OV@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:22 +0000

commit 924bf8c793cb1fee303c83f50632c68426cf8f12
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 16:04:11 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 15:55:38 2020 +0000

    tools/xenstore: rework path length check
    
    The different fixed limits for absolute and relative path lengths of
    Xenstore nodes make it possible to create per-domain nodes via
    absolute paths which are not accessible using relative paths, as the
    two limits differ by 1024 characters.
    
    Instead of this weird limits use only one limit, which applies to the
    relative path length of per-domain nodes and to the absolute path
    length of all other nodes. This means, the path length check is
    applied to the path after removing a possible start of
    "/local/domain/<n>/" with <n> being a domain id.
    
    There has been the request to be able to limit the path lengths even
    more, so an additional quota is added which can be applied to path
    lengths. It is XENSTORE_REL_PATH_MAX (2048) per default, but can be
    set to lower values. This is done via the new "-M" or "--path-max"
    option when invoking xenstored.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xenstore/xenstored_core.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 746a1247b3..3082a36d3a 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -102,6 +102,7 @@ int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
 int quota_nb_perms_per_node = 5;
+int quota_max_path_len = XENSTORE_REL_PATH_MAX;
 
 void trace(const char *fmt, ...)
 {
@@ -734,6 +735,9 @@ static bool valid_chars(const char *node)
 
 bool is_valid_nodename(const char *node)
 {
+	int local_off = 0;
+	unsigned int domid;
+
 	/* Must start in /. */
 	if (!strstarts(node, "/"))
 		return false;
@@ -746,7 +750,10 @@ bool is_valid_nodename(const char *node)
 	if (strstr(node, "//"))
 		return false;
 
-	if (strlen(node) > XENSTORE_ABS_PATH_MAX)
+	if (sscanf(node, "/local/domain/%5u/%n", &domid, &local_off) != 1)
+		local_off = 0;
+
+	if (strlen(node) > local_off + quota_max_path_len)
 		return false;
 
 	return valid_chars(node);
@@ -806,6 +813,8 @@ static struct node *get_node_canonicalized(struct connection *conn,
 	if (!canonical_name)
 		canonical_name = &tmp_name;
 	*canonical_name = canonicalize(conn, ctx, name);
+	if (!*canonical_name)
+		return NULL;
 	return get_node(conn, ctx, *canonical_name, perm);
 }
 
@@ -1926,6 +1935,7 @@ static void usage(void)
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
 "  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
+"  -M, --path-max <chars>  limit the allowed Xenstore node path length,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1947,6 +1957,7 @@ static struct option options[] = {
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
 	{ "perm-nb", 1, NULL, 'A' },
+	{ "path-max", 1, NULL, 'M' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1969,7 +1980,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:M:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2014,6 +2025,10 @@ int main(int argc, char *argv[])
 		case 'A':
 			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
 			break;
+			quota_max_path_len = strtol(optarg, NULL, 10);
+			quota_max_path_len = min(XENSTORE_REL_PATH_MAX,
+						 quota_max_path_len);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56148.98037 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0O2-00053U-I2; Thu, 17 Dec 2020 21:00:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56148.98037; Thu, 17 Dec 2020 21:00:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0O2-00053K-Eo; Thu, 17 Dec 2020 21:00:34 +0000
Received: by outflank-mailman (input) for mailman id 56148;
 Thu, 17 Dec 2020 21:00:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0O0-00053A-Um
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0O0-0007pv-Tx
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0O0-000658-Sh
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=90WF0ju4KE8T9zf8DA2IJMo9Cf449+eMOmbbDgasjFE=; b=ZUm3JjIfMCMdipHYpEvhgD2/nL
	Ftae77AsOdKF81HeTB/cPo3AF81YwkL3l5gxkAcytPXuLidKIYmHOezZW7ZiOCQKnwu4D57fQCYvI
	3N1tvDA1JzPVJpNNQ9ywojrJ2Ny5sdwUgcbIyyiA8Rfp/82pUL2/tj+uMwn0C9WBbX8E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools: allocate bitmaps in units of unsigned long
Message-Id: <E1kq0O0-000658-Sh@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:32 +0000

commit 8b90e311e0912b822621167621c515b41ea3d8e2
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Dec 9 16:54:49 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:23:14 2020 +0000

    tools: allocate bitmaps in units of unsigned long
    
    Allocate enough memory so that the returned pointer can be safely
    accessed as an array of unsigned long.
    
    The actual bitmap size in units of bytes, as returned by bitmap_size,
    remains unchanged.
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/ctrl/xc_bitops.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/libs/ctrl/xc_bitops.h b/tools/libs/ctrl/xc_bitops.h
index 3d3a09772a..d6c5ea5138 100644
--- a/tools/libs/ctrl/xc_bitops.h
+++ b/tools/libs/ctrl/xc_bitops.h
@@ -21,7 +21,10 @@ static inline unsigned long bitmap_size(unsigned long nr_bits)
 
 static inline void *bitmap_alloc(unsigned long nr_bits)
 {
-    return calloc(1, bitmap_size(nr_bits));
+    unsigned long longs;
+
+    longs = (nr_bits + BITS_PER_LONG - 1) / BITS_PER_LONG;
+    return calloc(longs, sizeof(unsigned long));
 }
 
 static inline void bitmap_set(void *addr, unsigned long nr_bits)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56149.98040 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OC-000556-JW; Thu, 17 Dec 2020 21:00:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56149.98040; Thu, 17 Dec 2020 21:00:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OC-00054y-GK; Thu, 17 Dec 2020 21:00:44 +0000
Received: by outflank-mailman (input) for mailman id 56149;
 Thu, 17 Dec 2020 21:00:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OB-00054l-3B
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OB-0007q7-2N
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OA-000670-WA
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9U/yFcU3peqCZpz8meN4IlK2eYH2mdg3CTUKGssBQdU=; b=MLjNWMkK8LPiCjMsjVh1SVWeHb
	ThcjnXft4igV/PROwZkKtZ92js3MMW9yDPoYVKrmvUjXtJOKiW32ycXTfsVCFiWBvS8XoVLCvgOc5
	Okp4dbr/R9hhuqU1mzxXRJmmBfxYRb302fapQyXc5JMVNcxM/zGZFuBtKuafergUubyA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools: remove unused ORDER_LONG
Message-Id: <E1kq0OA-000670-WA@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:42 +0000

commit 8862cb679cc23cb02fceaa897215f2ba58b3bed6
Author:     Olaf Hering <olaf@aepfle.de>
AuthorDate: Wed Dec 9 16:54:50 2020 +0100
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:23:17 2020 +0000

    tools: remove unused ORDER_LONG
    
    There are no users left, xenpaging has its own variant.
    The last user was removed with commit 11d0044a168994de85b9b328452292852aedc871
    
    Signed-off-by: Olaf Hering <olaf@aepfle.de>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/ctrl/xc_bitops.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tools/libs/ctrl/xc_bitops.h b/tools/libs/ctrl/xc_bitops.h
index d6c5ea5138..f0bac4a071 100644
--- a/tools/libs/ctrl/xc_bitops.h
+++ b/tools/libs/ctrl/xc_bitops.h
@@ -6,9 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* Needed by several includees, but no longer used for bitops. */
 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
 
 #define BITMAP_ENTRY(_nr,_bmap) ((_bmap))[(_nr) / 8]
 #define BITMAP_SHIFT(_nr) ((_nr) % 8)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:00:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:00:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56150.98045 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OM-00056V-LZ; Thu, 17 Dec 2020 21:00:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56150.98045; Thu, 17 Dec 2020 21:00:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OM-00056N-I1; Thu, 17 Dec 2020 21:00:54 +0000
Received: by outflank-mailman (input) for mailman id 56150;
 Thu, 17 Dec 2020 21:00:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OL-00056E-7P
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OL-0007qJ-6X
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OL-000686-5X
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:00:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BrjpfxFxiR5Be0JWVYzm/IPU5rpCELpaKHO/WScXERo=; b=hMD1oH/1ve0BhAONrLeJ9x+Vcz
	OXqO+cucz3a4VErxvEFYEqPVXL4RXX1WN1Z6Af6V41jteHPCuS8PSlY6hlDSIcX1LpmnyGVMej98P
	4Gc6aM6ErlIBBu7V2egU17hbe+6gdlqvTNyYTh8CTvq3ensSqj3Ef4l+bYb/rXsWFYdg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: s/pcidev/pci and remove DEFINE_DEVICE_TYPE_STRUCT_X
Message-Id: <E1kq0OL-000686-5X@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:00:53 +0000

commit e43780f15f13216c1ccef0bf143e089522661c21
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:09 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:16 2020 +0000

    libxl: s/pcidev/pci and remove DEFINE_DEVICE_TYPE_STRUCT_X
    
    The seemingly arbitrary use of 'pci' and 'pcidev' in the code in libxl_pci.c
    is confusing and also compromises use of some macros used for other device
    types. Indeed it seems that DEFINE_DEVICE_TYPE_STRUCT_X exists solely because
    of this duality.
    
    This patch purges use of 'pcidev' from the libxl internal code, but
    unfortunately the 'pcidevs' and 'num_pcidevs' fields in 'libxl_domain_config'
    are part of the API and need to be retained to avoid breaking callers,
    particularly libvirt.
    
    DEFINE_DEVICE_TYPE_STRUCT_X is still removed to avoid the special case in
    libxl_pci.c but DEFINE_DEVICE_TYPE_STRUCT is given an extra 'array' argument
    which is used to identify the fields in 'libxl_domain_config' relating to
    the device type.
    
    NOTE: Some of the more gross formatting errors (such as lack of spaces after
          keywords) that came into context have been fixed in libxl_pci.c.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h             |  10 +-
 tools/libs/light/libxl_9pfs.c     |   2 +-
 tools/libs/light/libxl_console.c  |   2 +-
 tools/libs/light/libxl_create.c   |   4 +-
 tools/libs/light/libxl_disk.c     |   2 +-
 tools/libs/light/libxl_internal.h |  29 +-
 tools/libs/light/libxl_nic.c      |   2 +-
 tools/libs/light/libxl_pci.c      | 570 +++++++++++++++++++-------------------
 tools/libs/light/libxl_pvcalls.c  |   2 +-
 tools/libs/light/libxl_usb.c      |   4 +-
 tools/libs/light/libxl_vdispl.c   |   2 +-
 tools/libs/light/libxl_vkb.c      |   2 +-
 tools/libs/light/libxl_vsnd.c     |   2 +-
 tools/libs/light/libxl_vtpm.c     |   2 +-
 tools/libs/util/libxlu_pci.c      |  36 +--
 15 files changed, 334 insertions(+), 337 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index eaffccb30f..733263522b 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -2307,15 +2307,15 @@ int libxl_device_pvcallsif_destroy(libxl_ctx *ctx, uint32_t domid,
 
 /* PCI Passthrough */
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
-                         libxl_device_pci *pcidev,
+                         libxl_device_pci *pci,
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
-                            libxl_device_pci *pcidev,
+                            libxl_device_pci *pci,
                             const libxl_asyncop_how *ao_how)
                             LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
-                             libxl_device_pci *pcidev,
+                             libxl_device_pci *pci,
                              const libxl_asyncop_how *ao_how)
                              LIBXL_EXTERNAL_CALLERS_ONLY;
 
@@ -2359,8 +2359,8 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pcidev, int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev, int rebind);
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
 
 /* CPUID handling */
diff --git a/tools/libs/light/libxl_9pfs.c b/tools/libs/light/libxl_9pfs.c
index e5c41e9a25..5ab0d3aa21 100644
--- a/tools/libs/light/libxl_9pfs.c
+++ b/tools/libs/light/libxl_9pfs.c
@@ -45,7 +45,7 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(p9)
 
 LIBXL_DEFINE_DEVICE_REMOVE(p9)
 
-DEFINE_DEVICE_TYPE_STRUCT(p9, 9PFS,
+DEFINE_DEVICE_TYPE_STRUCT(p9, 9PFS, p9s,
     .skip_attach = 1,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_p9,
diff --git a/tools/libs/light/libxl_console.c b/tools/libs/light/libxl_console.c
index 047d23d7ae..d8b2bc5465 100644
--- a/tools/libs/light/libxl_console.c
+++ b/tools/libs/light/libxl_console.c
@@ -725,7 +725,7 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(vfb)
 /* vfb */
 LIBXL_DEFINE_DEVICE_REMOVE(vfb)
 
-DEFINE_DEVICE_TYPE_STRUCT(vfb, VFB,
+DEFINE_DEVICE_TYPE_STRUCT(vfb, VFB, vfbs,
     .skip_attach = 1,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_vfb,
diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c
index 321a13e519..86f4a8369d 100644
--- a/tools/libs/light/libxl_create.c
+++ b/tools/libs/light/libxl_create.c
@@ -1809,7 +1809,7 @@ out:
 #define libxl__device_from_dtdev NULL
 #define libxl__device_dtdev_setdefault NULL
 #define libxl__device_dtdev_update_devid NULL
-static DEFINE_DEVICE_TYPE_STRUCT(dtdev, NONE);
+static DEFINE_DEVICE_TYPE_STRUCT(dtdev, NONE, dtdevs);
 
 const libxl__device_type *device_type_tbl[] = {
     &libxl__disk_devtype,
@@ -1817,7 +1817,7 @@ const libxl__device_type *device_type_tbl[] = {
     &libxl__vtpm_devtype,
     &libxl__usbctrl_devtype,
     &libxl__usbdev_devtype,
-    &libxl__pcidev_devtype,
+    &libxl__pci_devtype,
     &libxl__dtdev_devtype,
     &libxl__vdispl_devtype,
     &libxl__vsnd_devtype,
diff --git a/tools/libs/light/libxl_disk.c b/tools/libs/light/libxl_disk.c
index de183e0fb0..411ffeaca6 100644
--- a/tools/libs/light/libxl_disk.c
+++ b/tools/libs/light/libxl_disk.c
@@ -1374,7 +1374,7 @@ LIBXL_DEFINE_DEVICE_LIST(disk)
 
 #define libxl__device_disk_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT(disk, VBD,
+DEFINE_DEVICE_TYPE_STRUCT(disk, VBD, disks,
     .merge       = libxl_device_disk_merge,
     .dm_needed   = libxl_device_disk_dm_needed,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__disk_from_xenstore,
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index e26cda9b50..c2c5a9b926 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -1709,7 +1709,7 @@ _hidden int libxl__pci_topology_init(libxl__gc *gc,
 /* from libxl_pci */
 
 _hidden void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
-                                   libxl_device_pci *pcidev, bool starting,
+                                   libxl_device_pci *pci, bool starting,
                                    libxl__ao_device *aodev);
 _hidden void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
                                            libxl__multidev *);
@@ -3945,30 +3945,27 @@ struct libxl__device_type {
     device_set_xenstore_config_fn_t set_xenstore_config;
 };
 
-#define DEFINE_DEVICE_TYPE_STRUCT_X(name, sname, kind, ...)                    \
+#define DEFINE_DEVICE_TYPE_STRUCT(name, kind, array, ...)                      \
     const libxl__device_type libxl__ ## name ## _devtype = {                   \
-        .type          = LIBXL__DEVICE_KIND_ ## kind,                       \
-        .ptr_offset    = offsetof(libxl_domain_config, name ## s),             \
-        .num_offset    = offsetof(libxl_domain_config, num_ ## name ## s),     \
-        .dev_elem_size = sizeof(libxl_device_ ## sname),                       \
+        .type          = LIBXL__DEVICE_KIND_ ## kind,                          \
+        .ptr_offset    = offsetof(libxl_domain_config, array),                 \
+        .num_offset    = offsetof(libxl_domain_config, num_ ## array),         \
+        .dev_elem_size = sizeof(libxl_device_ ## name),                        \
         .add           = libxl__add_ ## name ## s,                             \
         .set_default   = (device_set_default_fn_t)                             \
-                         libxl__device_ ## sname ## _setdefault,               \
+                         libxl__device_ ## name ## _setdefault,                \
         .to_device     = (device_to_device_fn_t)libxl__device_from_ ## name,   \
-        .init          = (device_init_fn_t)libxl_device_ ## sname ## _init,    \
-        .copy          = (device_copy_fn_t)libxl_device_ ## sname ## _copy,    \
+        .init          = (device_init_fn_t)libxl_device_ ## name ## _init,     \
+        .copy          = (device_copy_fn_t)libxl_device_ ## name ## _copy,     \
         .dispose       = (device_dispose_fn_t)                                 \
-                         libxl_device_ ## sname ## _dispose,                   \
+                         libxl_device_ ## name ## _dispose,                    \
         .compare       = (device_compare_fn_t)                                 \
-                         libxl_device_ ## sname ## _compare,                   \
+                         libxl_device_ ## name ## _compare,                    \
         .update_devid  = (device_update_devid_fn_t)                            \
-                         libxl__device_ ## sname ## _update_devid,             \
+                         libxl__device_ ## name ## _update_devid,              \
         __VA_ARGS__                                                            \
     }
 
-#define DEFINE_DEVICE_TYPE_STRUCT(name, kind, ...)                             \
-    DEFINE_DEVICE_TYPE_STRUCT_X(name, name, kind, __VA_ARGS__)
-
 static inline void **libxl__device_type_get_ptr(
     const libxl__device_type *dt, const libxl_domain_config *d_config)
 {
@@ -3995,7 +3992,7 @@ extern const libxl__device_type libxl__nic_devtype;
 extern const libxl__device_type libxl__vtpm_devtype;
 extern const libxl__device_type libxl__usbctrl_devtype;
 extern const libxl__device_type libxl__usbdev_devtype;
-extern const libxl__device_type libxl__pcidev_devtype;
+extern const libxl__device_type libxl__pci_devtype;
 extern const libxl__device_type libxl__vdispl_devtype;
 extern const libxl__device_type libxl__p9_devtype;
 extern const libxl__device_type libxl__pvcallsif_devtype;
diff --git a/tools/libs/light/libxl_nic.c b/tools/libs/light/libxl_nic.c
index 0e5d120ae9..144e9e23e1 100644
--- a/tools/libs/light/libxl_nic.c
+++ b/tools/libs/light/libxl_nic.c
@@ -528,7 +528,7 @@ LIBXL_DEFINE_DEVICE_ADD(nic)
 LIBXL_DEFINE_DEVICES_ADD(nic)
 LIBXL_DEFINE_DEVICE_REMOVE(nic)
 
-DEFINE_DEVICE_TYPE_STRUCT(nic, VIF,
+DEFINE_DEVICE_TYPE_STRUCT(nic, VIF, nics,
     .update_config = libxl_device_nic_update_config,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__nic_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index bc5843b137..3340076d2c 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,51 +25,51 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pcidev_encode_bdf(libxl_device_pci *pcidev)
+static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pcidev->domain << 16;
-    value |= (pcidev->bus & 0xff) << 8;
-    value |= (pcidev->dev & 0x1f) << 3;
-    value |= (pcidev->func & 0x7);
+    value = pci->domain << 16;
+    value |= (pci->bus & 0xff) << 8;
+    value |= (pci->dev & 0x1f) << 3;
+    value |= (pci->func & 0x7);
 
     return value;
 }
 
-static void pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func, unsigned int vdevfn)
+static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                            unsigned int bus, unsigned int dev,
+                            unsigned int func, unsigned int vdevfn)
 {
-    pcidev->domain = domain;
-    pcidev->bus = bus;
-    pcidev->dev = dev;
-    pcidev->func = func;
-    pcidev->vdevfn = vdevfn;
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
 }
 
 static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             flexarray_t *back,
                                             int num,
-                                            const libxl_device_pci *pcidev)
+                                            const libxl_device_pci *pci)
 {
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
-    if (pcidev->vdevfn)
-        flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pcidev->vdevfn));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    if (pci->vdevfn)
+        flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
     flexarray_append(back,
               GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d",
-                             pcidev->msitranslate, pcidev->power_mgmt,
-                             pcidev->permissive));
+                             pci->msitranslate, pci->power_mgmt,
+                             pci->permissive));
     flexarray_append_pair(back, GCSPRINTF("state-%d", num), GCSPRINTF("%d", XenbusStateInitialising));
 }
 
-static void libxl__device_from_pcidev(libxl__gc *gc, uint32_t domid,
-                                      const libxl_device_pci *pcidev,
-                                      libxl__device *device)
+static void libxl__device_from_pci(libxl__gc *gc, uint32_t domid,
+                                   const libxl_device_pci *pci,
+                                   libxl__device *device)
 {
     device->backend_devid = 0;
     device->backend_domid = 0;
@@ -80,7 +80,7 @@ static void libxl__device_from_pcidev(libxl__gc *gc, uint32_t domid,
 }
 
 static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
-                                     const libxl_device_pci *pcidev,
+                                     const libxl_device_pci *pci,
                                      int num)
 {
     flexarray_t *front = NULL;
@@ -94,15 +94,15 @@ static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
     LOGD(DEBUG, domid, "Creating pci backend");
 
     /* add pci device */
-    libxl__device_from_pcidev(gc, domid, pcidev, &device);
+    libxl__device_from_pci(gc, domid, pci, &device);
 
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
     flexarray_append_pair(back, "online", "1");
     flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateInitialising));
     flexarray_append_pair(back, "domain", libxl__domid_to_name(gc, domid));
 
-    for (i = 0; i < num; i++, pcidev++)
-        libxl_create_pci_backend_device(gc, back, i, pcidev);
+    for (i = 0; i < num; i++, pci++)
+        libxl_create_pci_backend_device(gc, back, i, pci);
 
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num));
     flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", 0));
@@ -116,7 +116,7 @@ static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
 
 static int libxl__device_pci_add_xenstore(libxl__gc *gc,
                                           uint32_t domid,
-                                          const libxl_device_pci *pcidev,
+                                          const libxl_device_pci *pci,
                                           bool starting)
 {
     flexarray_t *back;
@@ -136,7 +136,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
                                                 LIBXL__DEVICE_KIND_PCI);
     num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
     if (!num_devs)
-        return libxl__create_pci_backend(gc, domid, pcidev, 1);
+        return libxl__create_pci_backend(gc, domid, pci, 1);
 
     libxl_domain_type domtype = libxl__domain_type(gc, domid);
     if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
@@ -151,7 +151,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
 
     LOGD(DEBUG, domid, "Adding new pci device to xenstore");
     num = atoi(num_devs);
-    libxl_create_pci_backend_device(gc, back, num, pcidev);
+    libxl_create_pci_backend_device(gc, back, num, pci);
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num + 1));
     if (!starting)
         flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateReconfiguring));
@@ -170,8 +170,8 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
         rc = libxl__get_domain_configuration(gc, domid, &d_config);
         if (rc) goto out;
 
-        device_add_domain_config(gc, &d_config, &libxl__pcidev_devtype,
-                                 pcidev);
+        device_add_domain_config(gc, &d_config, &libxl__pci_devtype,
+                                 pci);
 
         rc = libxl__dm_check_start(gc, &d_config, domid);
         if (rc) goto out;
@@ -201,7 +201,7 @@ out:
     return rc;
 }
 
-static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev)
+static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath;
@@ -231,8 +231,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pcidev->domain && bus == pcidev->bus &&
-            pcidev->dev == dev && pcidev->func == func) {
+        if (domain == pci->domain && bus == pci->bus &&
+            pci->dev == dev && pci->func == func) {
             break;
         }
     }
@@ -350,7 +350,7 @@ static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int
                     *list = realloc(*list, sizeof(libxl_device_pci) * ((*num) + 1));
                     if (*list == NULL)
                         return ERROR_NOMEM;
-                    pcidev_struct_fill(*list + *num, dom, bus, dev, func, 0);
+                    pci_struct_fill(*list + *num, dom, bus, dev, func, 0);
                     (*num)++;
                 }
             }
@@ -361,8 +361,8 @@ static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int
     return 0;
 }
 
-static int is_pcidev_in_array(libxl_device_pci *assigned, int num_assigned,
-                       int dom, int bus, int dev, int func)
+static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
+                           int dom, int bus, int dev, int func)
 {
     int i;
 
@@ -383,7 +383,7 @@ static int is_pcidev_in_array(libxl_device_pci *assigned, int num_assigned,
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
 static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
-                           libxl_device_pci *pcidev)
+                           libxl_device_pci *pci)
 {
     int rc, fd;
     char *buf;
@@ -394,8 +394,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pcidev->domain, pcidev->bus,
-                    pcidev->dev, pcidev->func);
+    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
+                    pci->dev, pci->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -411,7 +411,7 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcidevs = NULL, *new, *assigned;
+    libxl_device_pci *pcis = NULL, *new, *assigned;
     struct dirent *de;
     DIR *dir;
     int r, num_assigned;
@@ -436,40 +436,40 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        if (is_pcidev_in_array(assigned, num_assigned, dom, bus, dev, func))
+        if (is_pci_in_array(assigned, num_assigned, dom, bus, dev, func))
             continue;
 
-        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcidevs = new;
-        new = pcidevs + *num;
+        pcis = new;
+        new = pcis + *num;
 
         memset(new, 0, sizeof(*new));
-        pcidev_struct_fill(new, dom, bus, dev, func, 0);
+        pci_struct_fill(new, dom, bus, dev, func, 0);
         (*num)++;
     }
 
     closedir(dir);
 out:
     GC_FREE;
-    return pcidevs;
+    return pcis;
 }
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pcidev->domain,
-                           pcidev->bus,
-                           pcidev->dev,
-                           pcidev->func);
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -483,7 +483,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pcidev) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -495,11 +495,11 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pcidev,
     return 0;
 }
 
-static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
+static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -507,7 +507,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -515,18 +515,18 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pcidev)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
     return pci_device_vendor;
 }
 
-static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
+static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -534,7 +534,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -542,25 +542,25 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pcidev)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
     return pci_device_device;
 }
 
-static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
+static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+                     pci->domain, pci->bus, pci->dev, pci->func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -569,7 +569,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
     }
 
@@ -589,15 +589,15 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
     unsigned long class;
 
     for (i = 0 ; i < d_config->num_pcidevs ; i++) {
-        libxl_device_pci *pcidev = &d_config->pcidevs[i];
-        pt_vendor = sysfs_dev_get_vendor(gc, pcidev);
-        pt_device = sysfs_dev_get_device(gc, pcidev);
+        libxl_device_pci *pci = &d_config->pcidevs[i];
+        pt_vendor = sysfs_dev_get_vendor(gc, pci);
+        pt_device = sysfs_dev_get_device(gc, pci);
 
         if (pt_vendor == 0xffff || pt_device == 0xffff ||
             pt_vendor != 0x8086)
             continue;
 
-        if (sysfs_dev_get_class(gc, pcidev, &class))
+        if (sysfs_dev_get_class(gc, pci, &class))
             continue;
         if (class == 0x030000)
             return true;
@@ -621,8 +621,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for pcidev's BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pcidev)
+/* Scan through /sys/.../pciback/slots looking for pci's BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
 {
     FILE *f;
     int rc = 0;
@@ -635,11 +635,11 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pcidev)
         return ERROR_FAIL;
     }
 
-    while(fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func)==4) {
-        if(dom == pcidev->domain
-           && bus == pcidev->bus
-           && dev == pcidev->dev
-           && func == pcidev->func) {
+    while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
+        if (dom == pci->domain
+            && bus == pci->bus
+            && dev == pci->dev
+            && func == pci->func) {
             rc = 1;
             goto out;
         }
@@ -649,7 +649,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
 {
     char * spath;
     int rc;
@@ -665,8 +665,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pcidev->domain, pcidev->bus,
-                      pcidev->dev, pcidev->func);
+                      pci->domain, pci->bus,
+                      pci->dev, pci->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -677,40 +677,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pcidev)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
 {
     int rc;
 
-    if ( (rc=pciback_dev_has_slot(gc, pcidev)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcidev) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pcidev)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pcidev, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pcidev) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -721,49 +721,49 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pcidev)
 #define PCIBACK_INFO_PATH "/libxl/pciback"
 
 static void pci_assignable_driver_path_write(libxl__gc *gc,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             char *driver_path)
 {
     char *path;
 
     path = GCSPRINTF(PCIBACK_INFO_PATH"/"PCI_BDF_XSPATH"/driver_path",
-                     pcidev->domain,
-                     pcidev->bus,
-                     pcidev->dev,
-                     pcidev->func);
+                     pci->domain,
+                     pci->bus,
+                     pci->dev,
+                     pci->func);
     if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", driver_path) < 0 ) {
         LOGE(WARN, "Write of %s to node %s failed.", driver_path, path);
     }
 }
 
 static char * pci_assignable_driver_path_read(libxl__gc *gc,
-                                              libxl_device_pci *pcidev)
+                                              libxl_device_pci *pci)
 {
     return libxl__xs_read(gc, XBT_NULL,
                           GCSPRINTF(
                            PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH "/driver_path",
-                           pcidev->domain,
-                           pcidev->bus,
-                           pcidev->dev,
-                           pcidev->func));
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func));
 }
 
 static void pci_assignable_driver_path_remove(libxl__gc *gc,
-                                              libxl_device_pci *pcidev)
+                                              libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
     xs_rm(ctx->xsh, XBT_NULL,
           GCSPRINTF(PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH,
-                    pcidev->domain,
-                    pcidev->bus,
-                    pcidev->dev,
-                    pcidev->func) );
+                    pci->domain,
+                    pci->bus,
+                    pci->dev,
+                    pci->func) );
 }
 
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -773,10 +773,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pcidev->domain;
-    bus = pcidev->bus;
-    dev = pcidev->dev;
-    func = pcidev->func;
+    dom = pci->domain;
+    bus = pci->bus;
+    dev = pci->dev;
+    func = pci->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -786,7 +786,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pcidev);
+    rc = pciback_dev_is_assigned(gc, pci);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
@@ -796,7 +796,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pcidev, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -805,9 +805,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_assignable_driver_path_write(gc, pcidev, driver_path);
+            pci_assignable_driver_path_write(gc, pci, driver_path);
         } else if ( (driver_path =
-                     pci_assignable_driver_path_read(gc, pcidev)) != NULL ) {
+                     pci_assignable_driver_path_read(gc, pci)) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -815,10 +815,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_assignable_driver_path_remove(gc, pcidev);
+        pci_assignable_driver_path_remove(gc, pci);
     }
 
-    if ( pciback_dev_assign(gc, pcidev) ) {
+    if ( pciback_dev_assign(gc, pci) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
@@ -829,7 +829,7 @@ quarantine:
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pcidev_encode_bdf(pcidev),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -840,7 +840,7 @@ quarantine:
 }
 
 static int libxl__device_pci_assignable_remove(libxl__gc *gc,
-                                               libxl_device_pci *pcidev,
+                                               libxl_device_pci *pci,
                                                int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -848,24 +848,24 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pcidev_encode_bdf(pcidev));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcidev->domain, pcidev->bus,
-            pcidev->dev, pcidev->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
+            pci->dev, pci->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc=pciback_dev_is_assigned(gc, pcidev)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pcidev);
+        pciback_dev_unassign(gc, pci);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_assignable_driver_path_read(gc, pcidev);
+    driver_path = pci_assignable_driver_path_read(gc, pci);
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -873,12 +873,12 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pcidev) < 0 ) {
+                                 pci) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_assignable_driver_path_remove(gc, pcidev);
+            pci_assignable_driver_path_remove(gc, pci);
         }
     } else {
         if ( rebind ) {
@@ -890,26 +890,26 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     return 0;
 }
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pcidev,
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
                                     int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_add(gc, pcidev, rebind);
+    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev,
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
                                        int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_remove(gc, pcidev, rebind);
+    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
 
     GC_FREE;
     return rc;
@@ -920,7 +920,7 @@ int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pcidev,
  * driver. It also initialises a bit-mask of which function numbers are present
  * on that device.
 */
-static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pcidev, unsigned int *func_mask)
+static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigned int *func_mask)
 {
     struct dirent *de;
     DIR *dir;
@@ -940,11 +940,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pcidev, unsi
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pcidev->domain != dom )
+        if ( pci->domain != dom )
             continue;
-        if ( pcidev->bus != bus )
+        if ( pci->bus != bus )
             continue;
-        if ( pcidev->dev != dev )
+        if ( pci->dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -979,7 +979,7 @@ static int pci_ins_check(libxl__gc *gc, uint32_t domid, const char *state, void
 }
 
 static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
-                                 libxl_device_pci *pcidev)
+                                 libxl_device_pci *pci)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc = 0;
@@ -991,15 +991,15 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    if (pcidev->vdevfn) {
+    if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pcidev->domain, pcidev->bus, pcidev->dev,
-                         pcidev->func, pcidev->vdevfn, pcidev->msitranslate,
-                         pcidev->power_mgmt);
+                         pci->domain, pci->bus, pci->dev,
+                         pci->func, pci->vdevfn, pci->msitranslate,
+                         pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pcidev->domain,  pcidev->bus, pcidev->dev,
-                         pcidev->func, pcidev->msitranslate, pcidev->power_mgmt);
+                         pci->domain,  pci->bus, pci->dev,
+                         pci->func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1010,7 +1010,7 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     if ( rc < 0 )
         LOGD(ERROR, domid, "qemu refused to add device: %s", vdevfn);
-    else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 ) {
+    else if ( sscanf(vdevfn, "0x%x", &pci->vdevfn) != 1 ) {
         LOGD(ERROR, domid, "wrong format for the vdevfn: '%s'", vdevfn);
         rc = -1;
     }
@@ -1054,7 +1054,7 @@ typedef struct pci_add_state {
     libxl__xswait_state xswait;
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
-    libxl_device_pci *pcidev;
+    libxl_device_pci *pci;
     int pci_domid;
 } pci_add_state;
 
@@ -1072,7 +1072,7 @@ static void pci_add_dm_done(libxl__egc *,
 
 static void do_pci_add(libxl__egc *egc,
                        libxl_domid domid,
-                       libxl_device_pci *pcidev,
+                       libxl_device_pci *pci,
                        pci_add_state *pas)
 {
     STATE_AO_GC(pas->aodev->ao);
@@ -1082,7 +1082,7 @@ static void do_pci_add(libxl__egc *egc,
     /* init pci_add_state */
     libxl__xswait_init(&pas->xswait);
     libxl__ev_qmp_init(&pas->qmp);
-    pas->pcidev = pcidev;
+    pas->pci = pci;
     pas->pci_domid = domid;
     libxl__ev_time_init(&pas->timeout);
 
@@ -1128,7 +1128,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1136,7 +1136,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
     if (rc)
         goto out;
 
-    rc = qemu_pci_add_xenstore(gc, domid, pcidev);
+    rc = qemu_pci_add_xenstore(gc, domid, pci);
 out:
     pci_add_dm_done(egc, pas, rc); /* must be last */
 }
@@ -1149,7 +1149,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
     libxl__ev_qmp *const qmp = &pas->qmp;
 
     rc = libxl__ev_time_register_rel(ao, &pas->timeout,
@@ -1160,14 +1160,14 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+                           pci->bus, pci->dev, pci->func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pcidev->domain,
-                           pcidev->bus, pcidev->dev, pcidev->func);
-    if (pcidev->vdevfn) {
+                           "%04x:%02x:%02x.%01x", pci->domain,
+                           pci->bus, pci->dev, pci->func);
+    if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
-                               PCI_SLOT(pcidev->vdevfn),
-                               PCI_FUNC(pcidev->vdevfn));
+                               PCI_SLOT(pci->vdevfn),
+                               PCI_FUNC(pci->vdevfn));
     }
     /*
      * Version of QEMU prior to the XSA-131 fix did not support
@@ -1179,7 +1179,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
      * set the permissive flag if it is true. Users of older QEMU
      * have no reason to set the flag so this is ok.
      */
-    if (pcidev->permissive)
+    if (pci->permissive)
         libxl__qmp_param_add_bool(gc, &args, "permissive", true);
 
     qmp->ao = pas->aodev->ao;
@@ -1230,7 +1230,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
     int dev_slot, dev_func;
 
     /* Convenience aliases */
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) goto out;
 
@@ -1251,7 +1251,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pcidev->bus, pcidev->dev, pcidev->func);
+                         pci->bus, pci->dev, pci->func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1283,7 +1283,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
              }
              dev_func = libxl__json_object_get_integer(o);
 
-             pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
+             pci->vdevfn = PCI_DEVFN(dev_slot, dev_func);
 
              rc = 0;
              goto out;
@@ -1331,7 +1331,7 @@ static void pci_add_dm_done(libxl__egc *egc,
 
     /* Convenience aliases */
     bool starting = pas->starting;
-    libxl_device_pci *pcidev = pas->pcidev;
+    libxl_device_pci *pci = pas->pci;
     bool hvm = libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM;
 
     libxl__ev_qmp_dispose(gc, &pas->qmp);
@@ -1342,8 +1342,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1383,8 +1383,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain,
-                                pcidev->bus, pcidev->dev, pcidev->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                                pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1411,9 +1411,9 @@ static void pci_add_dm_done(libxl__egc *egc,
     fclose(f);
 
     /* Don't restrict writes to the PCI config space from this VM */
-    if (pcidev->permissive) {
+    if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             pcidev) < 0 ) {
+                             pci) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1422,14 +1422,14 @@ static void pci_add_dm_done(libxl__egc *egc,
 
 out_no_irq:
     if (!isstubdom) {
-        if (pcidev->rdm_policy == LIBXL_RDM_RESERVE_POLICY_STRICT) {
+        if (pci->rdm_policy == LIBXL_RDM_RESERVE_POLICY_STRICT) {
             flag &= ~XEN_DOMCTL_DEV_RDM_RELAXED;
-        } else if (pcidev->rdm_policy != LIBXL_RDM_RESERVE_POLICY_RELAXED) {
+        } else if (pci->rdm_policy != LIBXL_RDM_RESERVE_POLICY_RELAXED) {
             LOGED(ERROR, domainid, "unknown rdm check flag.");
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev), flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1438,7 +1438,7 @@ out_no_irq:
     }
 
     if (!starting && !libxl_get_stubdom_id(CTX, domid))
-        rc = libxl__device_pci_add_xenstore(gc, domid, pcidev, starting);
+        rc = libxl__device_pci_add_xenstore(gc, domid, pci, starting);
     else
         rc = 0;
 out:
@@ -1493,7 +1493,7 @@ int libxl__device_pci_setdefault(libxl__gc *gc, uint32_t domid,
 }
 
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
-                         libxl_device_pci *pcidev,
+                         libxl_device_pci *pci,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -1504,24 +1504,24 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_ADD;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_add(egc, domid, pcidev, false, aodev);
+    libxl__device_pci_add(egc, domid, pci, false, aodev);
     return AO_INPROGRESS;
 }
 
-static int libxl_pcidev_assignable(libxl_ctx *ctx, libxl_device_pci *pcidev)
+static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
     for (i = 0; i < num; i++) {
-        if (pcidevs[i].domain == pcidev->domain &&
-            pcidevs[i].bus == pcidev->bus &&
-            pcidevs[i].dev == pcidev->dev &&
-            pcidevs[i].func == pcidev->func)
+        if (pcis[i].domain == pci->domain &&
+            pcis[i].bus == pci->bus &&
+            pcis[i].dev == pci->dev &&
+            pcis[i].func == pci->func)
             break;
     }
-    free(pcidevs);
+    free(pcis);
     return i != num;
 }
 
@@ -1535,7 +1535,7 @@ static void device_pci_add_done(libxl__egc *egc,
     pci_add_state *, int rc);
 
 void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
-                           libxl_device_pci *pcidev, bool starting,
+                           libxl_device_pci *pci, bool starting,
                            libxl__ao_device *aodev)
 {
     STATE_AO_GC(aodev->ao);
@@ -1545,9 +1545,9 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     int stubdomid = 0;
     pci_add_state *pas;
 
-    /* Store *pcidev to be used by callbacks */
-    aodev->device_config = pcidev;
-    aodev->device_type = &libxl__pcidev_devtype;
+    /* Store *pci to be used by callbacks */
+    aodev->device_config = pci;
+    aodev->device_type = &libxl__pci_devtype;
 
     GCNEW(pas);
     pas->aodev = aodev;
@@ -1556,29 +1556,29 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->callback = device_pci_add_stubdom_done;
 
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev));
+        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func,
+                 pci->domain, pci->bus, pci->dev, pci->func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
         }
     }
 
-    rc = libxl__device_pci_setdefault(gc, domid, pcidev, !starting);
+    rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pcidev->seize && !pciback_dev_is_assigned(gc, pcidev)) {
-        rc = libxl__device_pci_assignable_add(gc, pcidev, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
+        rc = libxl__device_pci_assignable_add(gc, pci, 1);
         if ( rc )
             goto out;
     }
 
-    if (!libxl_pcidev_assignable(ctx, pcidev)) {
+    if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         rc = ERROR_FAIL;
         goto out;
     }
@@ -1589,25 +1589,25 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
              "cannot determine if device is assigned, refusing to continue");
         goto out;
     }
-    if ( is_pcidev_in_array(assigned, num_assigned, pcidev->domain,
-                     pcidev->bus, pcidev->dev, pcidev->func) ) {
+    if ( is_pci_in_array(assigned, num_assigned, pci->domain,
+                         pci->bus, pci->dev, pci->func) ) {
         LOGD(ERROR, domid, "PCI device already attached to a domain");
         rc = ERROR_FAIL;
         goto out;
     }
 
-    libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pcidev_s;
+        libxl_device_pci *pci_s;
 
-        GCNEW(pcidev_s);
-        libxl_device_pci_init(pcidev_s);
-        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
+        GCNEW(pci_s);
+        libxl_device_pci_init(pci_s);
+        libxl_device_pci_copy(CTX, pci_s, pci);
         pas->callback = device_pci_add_stubdom_wait;
 
-        do_pci_add(egc, stubdomid, pcidev_s, pas); /* must be last */
+        do_pci_add(egc, stubdomid, pci_s, pas); /* must be last */
         return;
     }
 
@@ -1664,42 +1664,42 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
     /* Convenience aliases */
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = aodev->device_config;
+    libxl_device_pci *pci = aodev->device_config;
 
     if (rc) goto out;
 
-    orig_vdev = pcidev->vdevfn & ~7U;
+    orig_vdev = pci->vdevfn & ~7U;
 
-    if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( !(pcidev->vdevfn >> 3) ) {
+    if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
+        if ( !(pci->vdevfn >> 3) ) {
             LOGD(ERROR, domid, "Must specify a v-slot for multi-function devices");
             rc = ERROR_INVAL;
             goto out;
         }
-        if ( pci_multifunction_check(gc, pcidev, &pfunc_mask) ) {
+        if ( pci_multifunction_check(gc, pci, &pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
-        pcidev->vfunc_mask &= pfunc_mask;
+        pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pcidev->func);
+        pfunc_mask = (1 << pci->func);
     }
 
-    for(rc = 0, i = 7; i >= 0; --i) {
+    for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
-            if ( pcidev->vfunc_mask == pfunc_mask ) {
-                pcidev->func = i;
-                pcidev->vdevfn = orig_vdev | i;
-            }else{
+            if ( pci->vfunc_mask == pfunc_mask ) {
+                pci->func = i;
+                pci->vdevfn = orig_vdev | i;
+            } else {
                 /* if not passing through multiple devices in a block make
                  * sure that virtual function number 0 is always used otherwise
                  * guest won't see the device
                  */
-                pcidev->vdevfn = orig_vdev;
+                pci->vdevfn = orig_vdev;
             }
             pas->callback = device_pci_add_done;
-            do_pci_add(egc, domid, pcidev, pas); /* must be last */
+            do_pci_add(egc, domid, pci, pas); /* must be last */
             return;
         }
     }
@@ -1715,13 +1715,13 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pcidev = aodev->device_config;
+    libxl_device_pci *pci = aodev->device_config;
 
     if (rc) {
         LOGD(ERROR, domid,
              "libxl__device_pci_add  failed for "
              "PCI device %x:%x:%x.%x (rc %d)",
-             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func,
+             pci->domain, pci->bus, pci->dev, pci->func,
              rc);
     }
     aodev->rc = rc;
@@ -1733,16 +1733,16 @@ typedef struct {
     libxl__ao_device *outer_aodev;
     libxl_domain_config *d_config;
     libxl_domid domid;
-} add_pcidevs_state;
+} add_pcis_state;
 
-static void add_pcidevs_done(libxl__egc *, libxl__multidev *, int rc);
+static void add_pcis_done(libxl__egc *, libxl__multidev *, int rc);
 
-static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
-                               libxl_domain_config *d_config,
-                               libxl__multidev *multidev)
+static void libxl__add_pcis(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                            libxl_domain_config *d_config,
+                            libxl__multidev *multidev)
 {
     AO_GC;
-    add_pcidevs_state *apds;
+    add_pcis_state *apds;
     int i;
 
     /* We need to start a new multidev in order to be able to execute
@@ -1752,7 +1752,7 @@ static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
     apds->outer_aodev = libxl__multidev_prepare(multidev);
     apds->d_config = d_config;
     apds->domid = domid;
-    apds->multidev.callback = add_pcidevs_done;
+    apds->multidev.callback = add_pcis_done;
     libxl__multidev_begin(ao, &apds->multidev);
 
     for (i = 0; i < d_config->num_pcidevs; i++) {
@@ -1764,11 +1764,11 @@ static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
     libxl__multidev_prepared(egc, &apds->multidev, 0);
 }
 
-static void add_pcidevs_done(libxl__egc *egc, libxl__multidev *multidev,
+static void add_pcis_done(libxl__egc *egc, libxl__multidev *multidev,
                              int rc)
 {
     EGC_GC;
-    add_pcidevs_state *apds = CONTAINER_OF(multidev, *apds, multidev);
+    add_pcis_state *apds = CONTAINER_OF(multidev, *apds, multidev);
 
     /* Convenience aliases */
     libxl_domain_config *d_config = apds->d_config;
@@ -1779,7 +1779,7 @@ static void add_pcidevs_done(libxl__egc *egc, libxl__multidev *multidev,
 
     if (d_config->num_pcidevs > 0 && !libxl_get_stubdom_id(CTX, domid)) {
         rc = libxl__create_pci_backend(gc, domid, d_config->pcidevs,
-            d_config->num_pcidevs);
+                                       d_config->num_pcidevs);
         if (rc < 0) {
             LOGD(ERROR, domid, "libxl_create_pci_backend failed: %d", rc);
             goto out;
@@ -1792,7 +1792,7 @@ out:
 }
 
 static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
-                                    libxl_device_pci *pcidev, int force)
+                                    libxl_device_pci *pci, int force)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *state;
@@ -1804,12 +1804,12 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
-                     pcidev->bus, pcidev->dev, pcidev->func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
+                     pci->bus, pci->dev, pci->func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
-    if ( !force && (pcidev->vdevfn & 0x7) == 0 ) {
+    if ( !force && (pci->vdevfn & 0x7) == 0 ) {
         libxl__qemu_traditional_cmd(gc, domid, "pci-rem");
         if (libxl__wait_for_device_model_deprecated(gc, domid, "pci-removed",
                                          NULL, NULL, NULL) < 0) {
@@ -1830,7 +1830,7 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
 typedef struct pci_remove_state {
     libxl__ao_device *aodev;
     libxl_domid domid;
-    libxl_device_pci *pcidev;
+    libxl_device_pci *pci;
     bool force;
     bool hvm;
     unsigned int orig_vdev;
@@ -1844,7 +1844,7 @@ typedef struct pci_remove_state {
 } pci_remove_state;
 
 static void libxl__device_pci_remove_common(libxl__egc *egc,
-    uint32_t domid, libxl_device_pci *pcidev, bool force,
+    uint32_t domid, libxl_device_pci *pci, bool force,
     libxl__ao_device *aodev);
 static void device_pci_remove_common_next(libxl__egc *egc,
     pci_remove_state *prs, int rc);
@@ -1869,7 +1869,7 @@ static void pci_remove_done(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 
 static void do_pci_remove(libxl__egc *egc, uint32_t domid,
-                          libxl_device_pci *pcidev, int force,
+                          libxl_device_pci *pci, int force,
                           pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
@@ -1887,8 +1887,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
     libxl__ptr_add(gc, assigned);
 
     rc = ERROR_INVAL;
-    if ( !is_pcidev_in_array(assigned, num, pcidev->domain,
-                      pcidev->bus, pcidev->dev, pcidev->func) ) {
+    if ( !is_pci_in_array(assigned, num, pci->domain,
+                          pci->bus, pci->dev, pci->func) ) {
         LOGD(ERROR, domainid, "PCI device not attached to this domain");
         goto out_fail;
     }
@@ -1917,8 +1917,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
-                                     pcidev->bus, pcidev->dev, pcidev->func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                                     pci->bus, pci->dev, pci->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -1953,8 +1953,8 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pcidev->domain,
-                               pcidev->bus, pcidev->dev, pcidev->func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                               pci->bus, pci->dev, pci->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1988,7 +1988,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1996,7 +1996,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
     if (rc)
         goto out;
 
-    rc = qemu_pci_remove_xenstore(gc, domid, pcidev, prs->force);
+    rc = qemu_pci_remove_xenstore(gc, domid, pci, prs->force);
 
 out:
     pci_remove_detatched(egc, prs, rc);
@@ -2010,7 +2010,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     int rc;
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     rc = libxl__ev_time_register_rel(ao, &prs->timeout,
                                      pci_remove_timeout,
@@ -2018,7 +2018,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pcidev->bus, pcidev->dev, pcidev->func);
+                           pci->bus, pci->dev, pci->func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2080,14 +2080,14 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl__ao *const ao = prs->aodev->ao;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     if (rc) goto out;
 
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pcidev->bus, pcidev->dev, pcidev->func);
+                         pci->bus, pci->dev, pci->func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2135,10 +2135,10 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     pci_remove_state *prs = CONTAINER_OF(ev, *prs, timeout);
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pcidev->bus, pcidev->dev, pcidev->func);
+         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2156,7 +2156,7 @@ static void pci_remove_detatched(libxl__egc *egc,
     bool isstubdom;
 
     /* Convenience aliases */
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
     libxl_domid domid = prs->domid;
 
     /* Cleaning QMP states ASAP */
@@ -2170,30 +2170,30 @@ static void pci_remove_detatched(libxl__egc *egc,
     isstubdom = libxl_is_stubdom(CTX, domid, &domainid);
 
     /* don't do multiple resets while some functions are still passed through */
-    if ( (pcidev->vdevfn & 0x7) == 0 ) {
-        libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+    if ((pci->vdevfn & 0x7) == 0) {
+        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid, pcidev_encode_bdf(pcidev));
+        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
 
     stubdomid = libxl_get_stubdom_id(CTX, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pcidev_s;
+        libxl_device_pci *pci_s;
         libxl__ao_device *const stubdom_aodev = &prs->stubdom_aodev;
 
-        GCNEW(pcidev_s);
-        libxl_device_pci_init(pcidev_s);
-        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
+        GCNEW(pci_s);
+        libxl_device_pci_init(pci_s);
+        libxl_device_pci_copy(CTX, pci_s, pci);
 
         libxl__prepare_ao_device(ao, stubdom_aodev);
         stubdom_aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
         stubdom_aodev->callback = pci_remove_stubdom_done;
         stubdom_aodev->update_json = prs->aodev->update_json;
-        libxl__device_pci_remove_common(egc, stubdomid, pcidev_s,
+        libxl__device_pci_remove_common(egc, stubdomid, pci_s,
                                         prs->force, stubdom_aodev);
         return;
     }
@@ -2219,14 +2219,14 @@ static void pci_remove_done(libxl__egc *egc,
 
     if (rc) goto out;
 
-    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pcidev);
+    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pci);
 out:
     device_pci_remove_common_next(egc, prs, rc);
 }
 
 static void libxl__device_pci_remove_common(libxl__egc *egc,
                                             uint32_t domid,
-                                            libxl_device_pci *pcidev,
+                                            libxl_device_pci *pci,
                                             bool force,
                                             libxl__ao_device *aodev)
 {
@@ -2237,7 +2237,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     GCNEW(prs);
     prs->aodev = aodev;
     prs->domid = domid;
-    prs->pcidev = pcidev;
+    prs->pci = pci;
     prs->force = force;
     libxl__xswait_init(&prs->xswait);
     libxl__ev_qmp_init(&prs->qmp);
@@ -2247,16 +2247,16 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
-    prs->orig_vdev = pcidev->vdevfn & ~7U;
+    prs->orig_vdev = pci->vdevfn & ~7U;
 
-    if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( pci_multifunction_check(gc, pcidev, &prs->pfunc_mask) ) {
+    if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
+        if ( pci_multifunction_check(gc, pci, &prs->pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
-        pcidev->vfunc_mask &= prs->pfunc_mask;
-    }else{
-        prs->pfunc_mask = (1 << pcidev->func);
+        pci->vfunc_mask &= prs->pfunc_mask;
+    } else {
+        prs->pfunc_mask = (1 << pci->func);
     }
 
     rc = 0;
@@ -2273,7 +2273,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_device_pci *const pci = prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
     const unsigned int orig_vdev = prs->orig_vdev;
@@ -2284,13 +2284,13 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         const int i = prs->next_func;
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
-            if ( pcidev->vfunc_mask == pfunc_mask ) {
-                pcidev->func = i;
-                pcidev->vdevfn = orig_vdev | i;
-            }else{
-                pcidev->vdevfn = orig_vdev;
+            if ( pci->vfunc_mask == pfunc_mask ) {
+                pci->func = i;
+                pci->vdevfn = orig_vdev | i;
+            } else {
+                pci->vdevfn = orig_vdev;
             }
-            do_pci_remove(egc, domid, pcidev, prs->force, prs);
+            do_pci_remove(egc, domid, pci, prs->force, prs);
             return;
         }
     }
@@ -2306,7 +2306,7 @@ out:
 }
 
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
-                            libxl_device_pci *pcidev,
+                            libxl_device_pci *pci,
                             const libxl_asyncop_how *ao_how)
 
 {
@@ -2318,12 +2318,12 @@ int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_remove_common(egc, domid, pcidev, false, aodev);
+    libxl__device_pci_remove_common(egc, domid, pci, false, aodev);
     return AO_INPROGRESS;
 }
 
 int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
-                             libxl_device_pci *pcidev,
+                             libxl_device_pci *pci,
                              const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -2334,7 +2334,7 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
     aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
     aodev->callback = device_addrm_aocomplete;
     aodev->update_json = true;
-    libxl__device_pci_remove_common(egc, domid, pcidev, true, aodev);
+    libxl__device_pci_remove_common(egc, domid, pci, true, aodev);
     return AO_INPROGRESS;
 }
 
@@ -2353,7 +2353,7 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
     if (s)
         vdevfn = strtol(s, (char **) NULL, 16);
 
-    pcidev_struct_fill(pci, domain, bus, dev, func, vdevfn);
+    pci_struct_fill(pci, domain, bus, dev, func, vdevfn);
 
     s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/opts-%d", be_path, nr));
     if (s) {
@@ -2398,7 +2398,7 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num
     GC_INIT(ctx);
     char *be_path;
     unsigned int n, i;
-    libxl_device_pci *pcidevs = NULL;
+    libxl_device_pci *pcis = NULL;
 
     *num = 0;
 
@@ -2407,28 +2407,28 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num
     if (libxl__device_pci_get_num(gc, be_path, &n))
         goto out;
 
-    pcidevs = calloc(n, sizeof(libxl_device_pci));
+    pcis = calloc(n, sizeof(libxl_device_pci));
 
     for (i = 0; i < n; i++)
-        libxl__device_pci_from_xs_be(gc, be_path, i, pcidevs + i);
+        libxl__device_pci_from_xs_be(gc, be_path, i, pcis + i);
 
     *num = n;
 out:
     GC_FREE;
-    return pcidevs;
+    return pcis;
 }
 
 void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
                                    libxl__multidev *multidev)
 {
     STATE_AO_GC(multidev->ao);
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_list(CTX, domid, &num);
-    if ( pcidevs == NULL )
+    pcis = libxl_device_pci_list(CTX, domid, &num);
+    if ( pcis == NULL )
         return;
-    libxl__ptr_add(gc, pcidevs);
+    libxl__ptr_add(gc, pcis);
 
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
@@ -2436,7 +2436,7 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
          * devices by the time we even get here!
          */
         libxl__ao_device *aodev = libxl__multidev_prepare(multidev);
-        libxl__device_pci_remove_common(egc, domid, pcidevs + i, true,
+        libxl__device_pci_remove_common(egc, domid, pcis + i, true,
                                         aodev);
     }
 }
@@ -2452,10 +2452,10 @@ int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid,
     for (i = 0 ; i < d_config->num_pcidevs ; i++) {
         uint64_t vga_iomem_start = 0xa0000 >> XC_PAGE_SHIFT;
         uint32_t stubdom_domid;
-        libxl_device_pci *pcidev = &d_config->pcidevs[i];
+        libxl_device_pci *pci = &d_config->pcidevs[i];
         unsigned long pci_device_class;
 
-        if (sysfs_dev_get_class(gc, pcidev, &pci_device_class))
+        if (sysfs_dev_get_class(gc, pci, &pci_device_class))
             continue;
         if (pci_device_class != 0x030000) /* VGA class */
             continue;
@@ -2494,7 +2494,7 @@ static int libxl_device_pci_compare(const libxl_device_pci *d1,
 
 #define libxl__device_pci_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT_X(pcidev, pci, PCI,
+DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .get_num = libxl__device_pci_get_num,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
diff --git a/tools/libs/light/libxl_pvcalls.c b/tools/libs/light/libxl_pvcalls.c
index 870318e716..1fbedf651c 100644
--- a/tools/libs/light/libxl_pvcalls.c
+++ b/tools/libs/light/libxl_pvcalls.c
@@ -34,4 +34,4 @@ static LIBXL_DEFINE_DEVICE_FROM_TYPE(pvcallsif)
 
 LIBXL_DEFINE_DEVICE_REMOVE(pvcallsif)
 
-DEFINE_DEVICE_TYPE_STRUCT(pvcallsif, PVCALLS);
+DEFINE_DEVICE_TYPE_STRUCT(pvcallsif, PVCALLS, pvcallsifs);
diff --git a/tools/libs/light/libxl_usb.c b/tools/libs/light/libxl_usb.c
index 171bb04439..c5ae59681c 100644
--- a/tools/libs/light/libxl_usb.c
+++ b/tools/libs/light/libxl_usb.c
@@ -2139,7 +2139,7 @@ void libxl_device_usbdev_list_free(libxl_device_usbdev *list, int nr)
 
 LIBXL_DEFINE_DEVID_TO_DEVICE(usbctrl)
 LIBXL_DEFINE_DEVICE_LIST(usbctrl)
-DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB,
+DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB, usbctrls,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__usbctrl_from_xenstore,
     .dm_needed = libxl_device_usbctrl_dm_needed
 );
@@ -2147,7 +2147,7 @@ DEFINE_DEVICE_TYPE_STRUCT(usbctrl, VUSB,
 #define libxl__device_from_usbdev NULL
 #define libxl__device_usbdev_update_devid NULL
 
-DEFINE_DEVICE_TYPE_STRUCT(usbdev, VUSB);
+DEFINE_DEVICE_TYPE_STRUCT(usbdev, VUSB, usbdevs);
 
 /*
  * Local variables:
diff --git a/tools/libs/light/libxl_vdispl.c b/tools/libs/light/libxl_vdispl.c
index 8ddc8940e9..60427c76c2 100644
--- a/tools/libs/light/libxl_vdispl.c
+++ b/tools/libs/light/libxl_vdispl.c
@@ -206,7 +206,7 @@ LIBXL_DEFINE_DEVICE_ADD(vdispl)
 LIBXL_DEFINE_DEVICE_REMOVE(vdispl)
 LIBXL_DEFINE_DEVICE_LIST(vdispl)
 
-DEFINE_DEVICE_TYPE_STRUCT(vdispl, VDISPL,
+DEFINE_DEVICE_TYPE_STRUCT(vdispl, VDISPL, vdispls,
     .update_config = (device_update_config_fn_t)libxl__update_config_vdispl,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__vdispl_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vkb.c b/tools/libs/light/libxl_vkb.c
index 4c44a813c1..bb88059f93 100644
--- a/tools/libs/light/libxl_vkb.c
+++ b/tools/libs/light/libxl_vkb.c
@@ -336,7 +336,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(vkb)
 LIBXL_DEFINE_DEVICE_LIST(vkb)
 LIBXL_DEFINE_DEVICE_REMOVE(vkb)
 
-DEFINE_DEVICE_TYPE_STRUCT(vkb, VKBD,
+DEFINE_DEVICE_TYPE_STRUCT(vkb, VKBD, vkbs,
     .skip_attach = 1,
     .dm_needed = libxl__device_vkb_dm_needed,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vsnd.c b/tools/libs/light/libxl_vsnd.c
index 0bc5f6dbb1..bb7942bbc9 100644
--- a/tools/libs/light/libxl_vsnd.c
+++ b/tools/libs/light/libxl_vsnd.c
@@ -670,7 +670,7 @@ LIBXL_DEFINE_DEVICE_ADD(vsnd)
 LIBXL_DEFINE_DEVICE_REMOVE(vsnd)
 LIBXL_DEFINE_DEVICE_LIST(vsnd)
 
-DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND,
+DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND, vsnds,
     .update_config = (device_update_config_fn_t) libxl__update_config_vsnd,
     .from_xenstore = (device_from_xenstore_fn_t) libxl__vsnd_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/light/libxl_vtpm.c b/tools/libs/light/libxl_vtpm.c
index dd00b267bb..0148c572d4 100644
--- a/tools/libs/light/libxl_vtpm.c
+++ b/tools/libs/light/libxl_vtpm.c
@@ -231,7 +231,7 @@ LIBXL_DEFINE_DEVICE_ADD(vtpm)
 LIBXL_DEFINE_DEVICE_REMOVE(vtpm)
 LIBXL_DEFINE_DEVICE_LIST(vtpm)
 
-DEFINE_DEVICE_TYPE_STRUCT(vtpm, VTPM,
+DEFINE_DEVICE_TYPE_STRUCT(vtpm, VTPM, vtpms,
     .update_config = libxl_device_vtpm_update_config,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__vtpm_from_xenstore,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 12fc0b3a7f..1d38fffce3 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -23,15 +23,15 @@ static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
     return 0;
 }
 
-static int pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func, unsigned int vdevfn)
+static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                           unsigned int bus, unsigned int dev,
+                           unsigned int func, unsigned int vdevfn)
 {
-    pcidev->domain = domain;
-    pcidev->bus = bus;
-    pcidev->dev = dev;
-    pcidev->func = func;
-    pcidev->vdevfn = vdevfn;
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
     return 0;
 }
 
@@ -47,7 +47,7 @@ static int pcidev_struct_fill(libxl_device_pci *pcidev, unsigned int domain,
 #define STATE_RDM_STRATEGY      10
 #define STATE_RESERVE_POLICY    11
 #define INVALID         0xffffffff
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str)
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
 {
     unsigned state = STATE_DOMAIN;
     unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
@@ -110,11 +110,11 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
                 }
                 *ptr = '\0';
                 if ( !strcmp(tok, "*") ) {
-                    pcidev->vfunc_mask = LIBXL_PCI_FUNC_ALL;
+                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
                 }else{
                     if ( hex_convert(tok, &func, 0x7) )
                         goto parse_error;
-                    pcidev->vfunc_mask = (1 << 0);
+                    pci->vfunc_mask = (1 << 0);
                 }
                 tok = ptr + 1;
             }
@@ -141,18 +141,18 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
                 state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
                 *ptr = '\0';
                 if ( !strcmp(optkey, "msitranslate") ) {
-                    pcidev->msitranslate = atoi(tok);
+                    pci->msitranslate = atoi(tok);
                 }else if ( !strcmp(optkey, "power_mgmt") ) {
-                    pcidev->power_mgmt = atoi(tok);
+                    pci->power_mgmt = atoi(tok);
                 }else if ( !strcmp(optkey, "permissive") ) {
-                    pcidev->permissive = atoi(tok);
+                    pci->permissive = atoi(tok);
                 }else if ( !strcmp(optkey, "seize") ) {
-                    pcidev->seize = atoi(tok);
+                    pci->seize = atoi(tok);
                 } else if (!strcmp(optkey, "rdm_policy")) {
                     if (!strcmp(tok, "strict")) {
-                        pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
                     } else if (!strcmp(tok, "relaxed")) {
-                        pcidev->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
                     } else {
                         XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
                                           " policy: 'strict' or 'relaxed'.",
@@ -175,7 +175,7 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
     assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
 
     /* Just a pretty way to fill in the values */
-    pcidev_struct_fill(pcidev, dom, bus, dev, func, vslot << 3);
+    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
 
     free(buf2);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56151.98049 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OW-000583-Qf; Thu, 17 Dec 2020 21:01:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56151.98049; Thu, 17 Dec 2020 21:01:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0OW-00057t-N5; Thu, 17 Dec 2020 21:01:04 +0000
Received: by outflank-mailman (input) for mailman id 56151;
 Thu, 17 Dec 2020 21:01:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OV-00057m-AQ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OV-0007sR-9d
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0OV-00069x-8p
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GHr3tKVh44VKqXJoH9i+tGDS+fWvpJ2f143gSaqF2p4=; b=B4Mkfk0lGQSBYIkWrFeluVBsEO
	LC5VOzxkIhjxuHjRoHqSqvUTkboa5ZIldGXY0U+ZzaOsIfmioq+T00Alb5YAbNedro/Yrnjz68Gcg
	C3w1I9HpTHlumimqUo2iho3q4eH0oZimTPJLVTgyW0YSyRF/0hDM6gzQ4AM4QpeoKmMw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xl: s/pcidev/pci where possible
Message-Id: <E1kq0OV-00069x-8p@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:03 +0000

commit 6c2590967fec90ec024a3608989b0796a043becf
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:10 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:20 2020 +0000

    xl: s/pcidev/pci where possible
    
    To improve naming consistency, replaces occurrences of 'pcidev' with 'pci'.
    The only remaining use of the term should be in relation to
    'libxl_domain_config' where there are fields named 'pcidevs' and 'num_pcidevs'.
    
    Purely cosmetic. No functional change.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xl/xl_parse.c | 22 ++++++++---------
 tools/xl/xl_pci.c   | 68 ++++++++++++++++++++++++++---------------------------
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index cae8eb679c..4ebf39620a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1473,21 +1473,21 @@ void parse_config_data(const char *config_source,
         d_config->num_pcidevs = 0;
         d_config->pcidevs = NULL;
         for(i = 0; (buf = xlu_cfg_get_listitem (pcis, i)) != NULL; i++) {
-            libxl_device_pci *pcidev;
-
-            pcidev = ARRAY_EXTEND_INIT_NODEVID(d_config->pcidevs,
-                                               d_config->num_pcidevs,
-                                               libxl_device_pci_init);
-            pcidev->msitranslate = pci_msitranslate;
-            pcidev->power_mgmt = pci_power_mgmt;
-            pcidev->permissive = pci_permissive;
-            pcidev->seize = pci_seize;
+            libxl_device_pci *pci;
+
+            pci = ARRAY_EXTEND_INIT_NODEVID(d_config->pcidevs,
+                                            d_config->num_pcidevs,
+                                            libxl_device_pci_init);
+            pci->msitranslate = pci_msitranslate;
+            pci->power_mgmt = pci_power_mgmt;
+            pci->permissive = pci_permissive;
+            pci->seize = pci_seize;
             /*
              * Like other pci option, the per-device policy always follows
              * the global policy by default.
              */
-            pcidev->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_bdf(config, pcidev, buf);
+            pci->rdm_policy = b_info->u.hvm.rdm.policy;
+            e = xlu_pci_parse_bdf(config, pci, buf);
             if (e) {
                 fprintf(stderr,
                         "unable to parse PCI BDF `%s' for passthrough\n",
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 58345bdae2..34fcf5a4fa 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -24,20 +24,20 @@
 
 static void pcilist(uint32_t domid)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_list(ctx, domid, &num);
-    if (pcidevs == NULL)
+    pcis = libxl_device_pci_list(ctx, domid, &num);
+    if (pcis == NULL)
         return;
     printf("Vdev Device\n");
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
-               (pcidevs[i].vdevfn >> 3) & 0x1f, pcidevs[i].vdevfn & 0x7,
-               pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
-        libxl_device_pci_dispose(&pcidevs[i]);
+               (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcidevs);
+    free(pcis);
 }
 
 int main_pcilist(int argc, char **argv)
@@ -57,28 +57,28 @@ int main_pcilist(int argc, char **argv)
 
 static int pcidetach(uint32_t domid, const char *bdf, int force)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
     if (force) {
-        if (libxl_device_pci_destroy(ctx, domid, &pcidev, 0))
+        if (libxl_device_pci_destroy(ctx, domid, &pci, 0))
             r = 1;
     } else {
-        if (libxl_device_pci_remove(ctx, domid, &pcidev, 0))
+        if (libxl_device_pci_remove(ctx, domid, &pci, 0))
             r = 1;
     }
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -108,24 +108,24 @@ int main_pcidetach(int argc, char **argv)
 
 static int pciattach(uint32_t domid, const char *bdf, const char *vs)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_add(ctx, domid, &pcidev, 0))
+    if (libxl_device_pci_add(ctx, domid, &pci, 0))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -155,19 +155,19 @@ int main_pciattach(int argc, char **argv)
 
 static void pciassignable_list(void)
 {
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcidevs = libxl_device_pci_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
 
-    if ( pcidevs == NULL )
+    if ( pcis == NULL )
         return;
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
-               pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func);
-        libxl_device_pci_dispose(&pcidevs[i]);
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcidevs);
+    free(pcis);
 }
 
 int main_pciassignable_list(int argc, char **argv)
@@ -184,24 +184,24 @@ int main_pciassignable_list(int argc, char **argv)
 
 static int pciassignable_add(const char *bdf, int rebind)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_add(ctx, &pcidev, rebind))
+    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -226,24 +226,24 @@ int main_pciassignable_add(int argc, char **argv)
 
 static int pciassignable_remove(const char *bdf, int rebind)
 {
-    libxl_device_pci pcidev;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pcidev);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcidev, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
         fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_remove(ctx, &pcidev, rebind))
+    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pcidev);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56152.98053 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Og-00059I-SK; Thu, 17 Dec 2020 21:01:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56152.98053; Thu, 17 Dec 2020 21:01:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Og-000599-Ol; Thu, 17 Dec 2020 21:01:14 +0000
Received: by outflank-mailman (input) for mailman id 56152;
 Thu, 17 Dec 2020 21:01:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Of-00058y-Dv
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Of-0007sj-D6
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Of-0006BC-CN
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YOEjtAjd2PCJ8/x6ZiaNB9ivsRtvxnkJl3sqSgmx6J8=; b=tMLtBQrd5tNoidfIsT9a2COHUI
	CmI4dt4w9Ui89hosmvt2rJ4pF+TuMrGEnpoq2YT8kMJAOYnXTnsdWGPx2yVu3eS4FIbwkT2rqasBX
	nIlI3bgmkSTw+G3Txg3WgkxUIBeG/xQOP5KDIDjrOummdn2s76m+zQTsR78s1vkpqp50=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: make libxl__device_list() work correctly for LIBXL__DEVICE_KIND_PCI...
Message-Id: <E1kq0Of-0006BC-CN@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:13 +0000

commit fce69998edd7583417c833fe1bf3347efcdc93e7
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:11 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: make libxl__device_list() work correctly for LIBXL__DEVICE_KIND_PCI...
    
    ... devices.
    
    Currently there is an assumption built into libxl__device_list() that device
    backends are fully enumarated under the '/libxl' path in xenstore. This is
    not the case for PCI backend devices, which are only properly enumerated
    under '/local/domain/0/backend'.
    
    This patch adds a new get_path() method to libxl__device_type to allow a
    backend implementation (such as PCI) to specify the xenstore path where
    devices are enumerated and modifies libxl__device_list() to use this method
    if it is available. Also, if the get_num() method is defined then the
    from_xenstore() method expects to be passed the backend path without the device
    number concatenated, so this issue is also rectified.
    
    Having made libxl__device_list() work correctly, this patch removes the
    open-coded libxl_pci_device_pci_list() in favour of an evaluation of the
    LIBXL_DEFINE_DEVICE_LIST() macro. This has the side-effect of also defining
    libxl_pci_device_pci_list_free() which will be used in subsequent patches.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h             |  7 +++++
 tools/libs/light/libxl_device.c   | 66 +++++++++++++++++++++------------------
 tools/libs/light/libxl_internal.h |  2 ++
 tools/libs/light/libxl_pci.c      | 29 +++++------------
 4 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 733263522b..bb7fc893fc 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -451,6 +451,12 @@
  */
 #define LIBXL_HAVE_VIRIDIAN_EX_PROCESSOR_MASKS 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_LIST_FREE indicates that the
+ * libxl_device_pci_list_free() function is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_LIST_FREE 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2321,6 +2327,7 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
 
 libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid,
                                         int *num);
+void libxl_device_pci_list_free(libxl_device_pci* list, int num);
 
 /*
  * Turns the current process into a backend device service daemon
diff --git a/tools/libs/light/libxl_device.c b/tools/libs/light/libxl_device.c
index e081faf9a9..ac173a043d 100644
--- a/tools/libs/light/libxl_device.c
+++ b/tools/libs/light/libxl_device.c
@@ -2011,7 +2011,7 @@ void *libxl__device_list(libxl__gc *gc, const libxl__device_type *dt,
     void *r = NULL;
     void *list = NULL;
     void *item = NULL;
-    char *libxl_path;
+    char *path;
     char **dir = NULL;
     unsigned int ndirs = 0;
     unsigned int ndevs = 0;
@@ -2019,42 +2019,46 @@ void *libxl__device_list(libxl__gc *gc, const libxl__device_type *dt,
 
     *num = 0;
 
-    libxl_path = GCSPRINTF("%s/device/%s",
-                           libxl__xs_libxl_path(gc, domid),
-                           libxl__device_kind_to_string(dt->type));
-
-    dir = libxl__xs_directory(gc, XBT_NULL, libxl_path, &ndirs);
+    if (dt->get_path) {
+        rc = dt->get_path(gc, domid, &path);
+        if (rc) goto out;
+    } else {
+        path = GCSPRINTF("%s/device/%s",
+                         libxl__xs_libxl_path(gc, domid),
+                         libxl__device_kind_to_string(dt->type));
+    }
 
-    if (dir && ndirs) {
-        if (dt->get_num) {
-            if (ndirs != 1) {
-                LOGD(ERROR, domid, "multiple entries in %s\n", libxl_path);
-                rc = ERROR_FAIL;
-                goto out;
-            }
-            rc = dt->get_num(gc, GCSPRINTF("%s/%s", libxl_path, *dir), &ndevs);
-            if (rc) goto out;
-        } else {
+    if (dt->get_num) {
+        rc = dt->get_num(gc, path, &ndevs);
+        if (rc) goto out;
+    } else {
+        dir = libxl__xs_directory(gc, XBT_NULL, path, &ndirs);
+        if (dir && ndirs)
             ndevs = ndirs;
-        }
-        list = libxl__malloc(NOGC, dt->dev_elem_size * ndevs);
-        item = list;
+    }
 
-        while (*num < ndevs) {
-            dt->init(item);
+    if (!ndevs)
+        return NULL;
 
-            if (dt->from_xenstore) {
-                int nr = dt->get_num ? *num : atoi(*dir);
-                char *device_libxl_path = GCSPRINTF("%s/%s", libxl_path, *dir);
-                rc = dt->from_xenstore(gc, device_libxl_path, nr, item);
-                if (rc) goto out;
-            }
+    list = libxl__malloc(NOGC, dt->dev_elem_size * ndevs);
+    item = list;
 
-            item = (uint8_t *)item + dt->dev_elem_size;
-            ++(*num);
-            if (!dt->get_num)
-                ++dir;
+    while (*num < ndevs) {
+        dt->init(item);
+
+        if (dt->from_xenstore) {
+            int nr = dt->get_num ? *num : atoi(*dir);
+            char *device_path = dt->get_num ? path :
+                GCSPRINTF("%s/%d", path, nr);
+
+            rc = dt->from_xenstore(gc, device_path, nr, item);
+            if (rc) goto out;
         }
+
+        item = (uint8_t *)item + dt->dev_elem_size;
+        ++(*num);
+        if (!dt->get_num)
+            ++dir;
     }
 
     r = list;
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index c2c5a9b926..d0c23def3c 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -3917,6 +3917,7 @@ typedef int (*device_dm_needed_fn_t)(void *, unsigned);
 typedef void (*device_update_config_fn_t)(libxl__gc *, void *, void *);
 typedef int (*device_update_devid_fn_t)(libxl__gc *, uint32_t, void *);
 typedef int (*device_get_num_fn_t)(libxl__gc *, const char *, unsigned int *);
+typedef int (*device_get_path_fn_t)(libxl__gc *, uint32_t, char **);
 typedef int (*device_from_xenstore_fn_t)(libxl__gc *, const char *,
                                          libxl_devid, void *);
 typedef int (*device_set_xenstore_config_fn_t)(libxl__gc *, uint32_t, void *,
@@ -3941,6 +3942,7 @@ struct libxl__device_type {
     device_update_config_fn_t       update_config;
     device_update_devid_fn_t        update_devid;
     device_get_num_fn_t             get_num;
+    device_get_path_fn_t            get_path;
     device_from_xenstore_fn_t       from_xenstore;
     device_set_xenstore_config_fn_t set_xenstore_config;
 };
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 3340076d2c..d536702ac4 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -2393,29 +2393,13 @@ static int libxl__device_pci_get_num(libxl__gc *gc, const char *be_path,
     return rc;
 }
 
-libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num)
+static int libxl__device_pci_get_path(libxl__gc *gc, uint32_t domid,
+                                      char **path)
 {
-    GC_INIT(ctx);
-    char *be_path;
-    unsigned int n, i;
-    libxl_device_pci *pcis = NULL;
-
-    *num = 0;
-
-    be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
-                                                LIBXL__DEVICE_KIND_PCI);
-    if (libxl__device_pci_get_num(gc, be_path, &n))
-        goto out;
+    *path = libxl__domain_device_backend_path(gc, 0, domid, 0,
+                                              LIBXL__DEVICE_KIND_PCI);
 
-    pcis = calloc(n, sizeof(libxl_device_pci));
-
-    for (i = 0; i < n; i++)
-        libxl__device_pci_from_xs_be(gc, be_path, i, pcis + i);
-
-    *num = n;
-out:
-    GC_FREE;
-    return pcis;
+    return 0;
 }
 
 void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
@@ -2492,10 +2476,13 @@ static int libxl_device_pci_compare(const libxl_device_pci *d1,
     return COMPARE_PCI(d1, d2);
 }
 
+LIBXL_DEFINE_DEVICE_LIST(pci)
+
 #define libxl__device_pci_update_devid NULL
 
 DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .get_num = libxl__device_pci_get_num,
+    .get_path = libxl__device_pci_get_path,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56153.98056 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Oq-0005Ah-Tm; Thu, 17 Dec 2020 21:01:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56153.98056; Thu, 17 Dec 2020 21:01:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Oq-0005AZ-QU; Thu, 17 Dec 2020 21:01:24 +0000
Received: by outflank-mailman (input) for mailman id 56153;
 Thu, 17 Dec 2020 21:01:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Op-0005AQ-ID
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Op-0007sr-HR
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Op-0006C3-FP
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ZZzXQ7DiUqpotp9turfZjAAhYmShhtcJpMERxtq97Ec=; b=h4DTgUzrDLlw3aOm8vAsfOkNxB
	GRuunWHT8GUH94DKS2RrEABOI2IopxcV0Um3P+A3r5BvMQKTr3WVngUkdy9+5mC27nS68SQgefEmx
	Q7mm0QEL/6x6SDxmebvLXIM+gSA+ZIbF3PR/LAuvzag3XYURBgEABw91LujLtTpIbpu0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: Make sure devices added by pci-attach are reflected in the config
Message-Id: <E1kq0Op-0006C3-FP@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:23 +0000

commit 0fdb48ffe7a1a56745b999506bf572e260e8ae0a
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:12 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: Make sure devices added by pci-attach are reflected in the config
    
    Currently libxl__device_pci_add_xenstore() is broken in that does not
    update the domain's configuration for the first device added (which causes
    creation of the overall backend area in xenstore). This can be easily observed
    by running 'xl list -l' after adding a single device: the device will be
    missing.
    
    This patch fixes the problem and adds a DEBUG log line to allow easy
    verification that the domain configuration is being modified. Also, the use
    of libxl__device_generic_add() is dropped as it leads to a confusing situation
    where only partial backend information is written under the xenstore
    '/libxl' path. For LIBXL__DEVICE_KIND_PCI devices the only definitive
    information in xenstore is under '/local/domain/0/backend' (the '0' being
    hard-coded).
    
    NOTE: This patch includes a whitespace in add_pcis_done().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 87 +++++++++++++++++++++++---------------------
 1 file changed, 45 insertions(+), 42 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index d536702ac4..3f85f0d762 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -79,39 +79,55 @@ static void libxl__device_from_pci(libxl__gc *gc, uint32_t domid,
     device->kind = LIBXL__DEVICE_KIND_PCI;
 }
 
-static int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
-                                     const libxl_device_pci *pci,
-                                     int num)
+static void libxl__create_pci_backend(libxl__gc *gc, xs_transaction_t t,
+                                      uint32_t domid, const libxl_device_pci *pci)
 {
-    flexarray_t *front = NULL;
-    flexarray_t *back = NULL;
-    libxl__device device;
-    int i;
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    flexarray_t *front, *back;
+    char *fe_path, *be_path;
+    struct xs_permissions fe_perms[2], be_perms[2];
+
+    LOGD(DEBUG, domid, "Creating pci backend");
 
     front = flexarray_make(gc, 16, 1);
     back = flexarray_make(gc, 16, 1);
 
-    LOGD(DEBUG, domid, "Creating pci backend");
-
-    /* add pci device */
-    libxl__device_from_pci(gc, domid, pci, &device);
+    fe_path = libxl__domain_device_frontend_path(gc, domid, 0,
+                                                 LIBXL__DEVICE_KIND_PCI);
+    be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
+                                                LIBXL__DEVICE_KIND_PCI);
 
+    flexarray_append_pair(back, "frontend", fe_path);
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
-    flexarray_append_pair(back, "online", "1");
+    flexarray_append_pair(back, "online", GCSPRINTF("%d", 1));
     flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateInitialising));
     flexarray_append_pair(back, "domain", libxl__domid_to_name(gc, domid));
 
-    for (i = 0; i < num; i++, pci++)
-        libxl_create_pci_backend_device(gc, back, i, pci);
+    be_perms[0].id = 0;
+    be_perms[0].perms = XS_PERM_NONE;
+    be_perms[1].id = domid;
+    be_perms[1].perms = XS_PERM_READ;
+
+    xs_rm(ctx->xsh, t, be_path);
+    xs_mkdir(ctx->xsh, t, be_path);
+    xs_set_permissions(ctx->xsh, t, be_path, be_perms,
+                       ARRAY_SIZE(be_perms));
+    libxl__xs_writev(gc, t, be_path, libxl__xs_kvs_of_flexarray(gc, back));
 
-    flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num));
+    flexarray_append_pair(front, "backend", be_path);
     flexarray_append_pair(front, "backend-id", GCSPRINTF("%d", 0));
     flexarray_append_pair(front, "state", GCSPRINTF("%d", XenbusStateInitialising));
 
-    return libxl__device_generic_add(gc, XBT_NULL, &device,
-                                     libxl__xs_kvs_of_flexarray(gc, back),
-                                     libxl__xs_kvs_of_flexarray(gc, front),
-                                     NULL);
+    fe_perms[0].id = domid;
+    fe_perms[0].perms = XS_PERM_NONE;
+    fe_perms[1].id = 0;
+    fe_perms[1].perms = XS_PERM_READ;
+
+    xs_rm(ctx->xsh, t, fe_path);
+    xs_mkdir(ctx->xsh, t, fe_path);
+    xs_set_permissions(ctx->xsh, t, fe_path,
+                       fe_perms, ARRAY_SIZE(fe_perms));
+    libxl__xs_writev(gc, t, fe_path, libxl__xs_kvs_of_flexarray(gc, front));
 }
 
 static int libxl__device_pci_add_xenstore(libxl__gc *gc,
@@ -135,8 +151,6 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
     be_path = libxl__domain_device_backend_path(gc, 0, domid, 0,
                                                 LIBXL__DEVICE_KIND_PCI);
     num_devs = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/num_devs", be_path));
-    if (!num_devs)
-        return libxl__create_pci_backend(gc, domid, pci, 1);
 
     libxl_domain_type domtype = libxl__domain_type(gc, domid);
     if (domtype == LIBXL_DOMAIN_TYPE_INVALID)
@@ -150,17 +164,17 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
     back = flexarray_make(gc, 16, 1);
 
     LOGD(DEBUG, domid, "Adding new pci device to xenstore");
-    num = atoi(num_devs);
+    num = num_devs ? atoi(num_devs) : 0;
     libxl_create_pci_backend_device(gc, back, num, pci);
     flexarray_append_pair(back, "num_devs", GCSPRINTF("%d", num + 1));
-    if (!starting)
+    if (num && !starting)
         flexarray_append_pair(back, "state", GCSPRINTF("%d", XenbusStateReconfiguring));
 
     /*
      * Stubdomin config is derived from its target domain, it doesn't have
      * its own file.
      */
-    if (!is_stubdomain) {
+    if (!is_stubdomain && !starting) {
         lock = libxl__lock_domain_userdata(gc, domid);
         if (!lock) {
             rc = ERROR_LOCK_FAIL;
@@ -170,6 +184,7 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
         rc = libxl__get_domain_configuration(gc, domid, &d_config);
         if (rc) goto out;
 
+        LOGD(DEBUG, domid, "Adding new pci device to config");
         device_add_domain_config(gc, &d_config, &libxl__pci_devtype,
                                  pci);
 
@@ -186,6 +201,10 @@ static int libxl__device_pci_add_xenstore(libxl__gc *gc,
             if (rc) goto out;
         }
 
+        /* This is the first device, so create the backend */
+        if (!num_devs)
+            libxl__create_pci_backend(gc, t, domid, pci);
+
         libxl__xs_writev(gc, t, be_path, libxl__xs_kvs_of_flexarray(gc, back));
 
         rc = libxl__xs_transaction_commit(gc, &t);
@@ -1437,7 +1456,7 @@ out_no_irq:
         }
     }
 
-    if (!starting && !libxl_get_stubdom_id(CTX, domid))
+    if (!libxl_get_stubdom_id(CTX, domid))
         rc = libxl__device_pci_add_xenstore(gc, domid, pci, starting);
     else
         rc = 0;
@@ -1765,28 +1784,12 @@ static void libxl__add_pcis(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
 }
 
 static void add_pcis_done(libxl__egc *egc, libxl__multidev *multidev,
-                             int rc)
+                          int rc)
 {
     EGC_GC;
     add_pcis_state *apds = CONTAINER_OF(multidev, *apds, multidev);
-
-    /* Convenience aliases */
-    libxl_domain_config *d_config = apds->d_config;
-    libxl_domid domid = apds->domid;
     libxl__ao_device *aodev = apds->outer_aodev;
 
-    if (rc) goto out;
-
-    if (d_config->num_pcidevs > 0 && !libxl_get_stubdom_id(CTX, domid)) {
-        rc = libxl__create_pci_backend(gc, domid, d_config->pcidevs,
-                                       d_config->num_pcidevs);
-        if (rc < 0) {
-            LOGD(ERROR, domid, "libxl_create_pci_backend failed: %d", rc);
-            goto out;
-        }
-    }
-
-out:
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56154.98062 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0P0-0005Bw-1a; Thu, 17 Dec 2020 21:01:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56154.98062; Thu, 17 Dec 2020 21:01:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Oz-0005Bo-UB; Thu, 17 Dec 2020 21:01:33 +0000
Received: by outflank-mailman (input) for mailman id 56154;
 Thu, 17 Dec 2020 21:01:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Oz-0005Bj-L0
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Oz-0007sy-KE
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Oz-0006Cn-JX
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=d/BZxmFnhWDli70F4wbaA1faY/SZd7SlSGhZe9u0Lwk=; b=ubQuBM1g016lO/Mil2L/5D+y52
	4hDoGVaQBJ3J4r7uXlaT5LC61ZQv95srdAgobEEXL5haxCn3rO1zM0XtFsPeosOebhXlFP5owVHQI
	aJqcA3gQ6vJTjxPCAhWtmGLIbGiMJqDNqLegnba1z5vK1m3pCkazhYjrYTaHPPNd/K8w=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: add/recover 'rdm_policy' to/from PCI backend in xenstore
Message-Id: <E1kq0Oz-0006Cn-JX@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:33 +0000

commit d8cba539f2d94385fd2d52483d3efec72b080811
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:13 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: add/recover 'rdm_policy' to/from PCI backend in xenstore
    
    Other parameters, such as 'msitranslate' and 'permissive' are dealt with
    but 'rdm_policy' appears to be have been completely missed.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 3f85f0d762..2a5a4db976 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -61,9 +61,9 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
     flexarray_append(back,
-              GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d",
-                             pci->msitranslate, pci->power_mgmt,
-                             pci->permissive));
+              GCSPRINTF("msitranslate=%d,power_mgmt=%d,permissive=%d,rdm_policy=%s",
+                        pci->msitranslate, pci->power_mgmt,
+                        pci->permissive, libxl_rdm_reserve_policy_to_string(pci->rdm_policy)));
     flexarray_append_pair(back, GCSPRINTF("state-%d", num), GCSPRINTF("%d", XenbusStateInitialising));
 }
 
@@ -2374,6 +2374,9 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
             } else if (!strcmp(p, "permissive")) {
                 p = strtok_r(NULL, ",=", &saveptr);
                 pci->permissive = atoi(p);
+            } else if (!strcmp(p, "rdm_policy")) {
+                p = strtok_r(NULL, ",=", &saveptr);
+                libxl_rdm_reserve_policy_from_string(p, &pci->rdm_policy);
             }
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56155.98065 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PB-0005DN-2I; Thu, 17 Dec 2020 21:01:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56155.98065; Thu, 17 Dec 2020 21:01:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PA-0005DG-Vl; Thu, 17 Dec 2020 21:01:44 +0000
Received: by outflank-mailman (input) for mailman id 56155;
 Thu, 17 Dec 2020 21:01:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0P9-0005D8-Ny
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0P9-0007tC-NF
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0P9-0006DT-MO
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4b4lPqQ/GkjjlsKwHkuBRxUhTxGS4W/+TTziGETIiU4=; b=G9G/2ubBApxQYEv7Fbbx4yf4RD
	PR7mDid3lAgaRoE4urfAZg3exBUg9wpbRF62UeGv23J80E5APN6LY2AutCbZ3fqmpsj+rQPgjbe9p
	uhB6cV1ty5nwC9O8YQvJrgeFD5pI9MF22hvr5Qa9IH8DDuMtA28s5Bh1cmWU4sqltRuM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: s/detatched/detached in libxl_pci.c
Message-Id: <E1kq0P9-0006DT-MO@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:43 +0000

commit 33e1c5a5a8953993ae0b2f28825058b539c05831
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:14 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: s/detatched/detached in libxl_pci.c
    
    Simply spelling correction. Purely cosmetic fix.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 2a5a4db976..b6d3bd29b7 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1864,7 +1864,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
 static void pci_remove_timeout(libxl__egc *egc,
     libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
-static void pci_remove_detatched(libxl__egc *egc,
+static void pci_remove_detached(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 static void pci_remove_stubdom_done(libxl__egc *egc,
     libxl__ao_device *aodev);
@@ -1978,7 +1978,7 @@ skip1:
 skip_irq:
     rc = 0;
 out_fail:
-    pci_remove_detatched(egc, prs, rc); /* must be last */
+    pci_remove_detached(egc, prs, rc); /* must be last */
 }
 
 static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
@@ -2002,7 +2002,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
     rc = qemu_pci_remove_xenstore(gc, domid, pci, prs->force);
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_device_del(libxl__egc *egc,
@@ -2028,7 +2028,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
@@ -2051,7 +2051,7 @@ static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc, libxl__ev_time *ev,
@@ -2067,7 +2067,7 @@ static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc, libxl__ev_time *ev,
     return;
 
 out:
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
 static void pci_remove_qmp_query_cb(libxl__egc *egc,
@@ -2127,7 +2127,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     }
 
 out:
-    pci_remove_detatched(egc, prs, rc); /* must be last */
+    pci_remove_detached(egc, prs, rc); /* must be last */
 }
 
 static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
@@ -2146,12 +2146,12 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
      * error */
-    pci_remove_detatched(egc, prs, rc);
+    pci_remove_detached(egc, prs, rc);
 }
 
-static void pci_remove_detatched(libxl__egc *egc,
-                                 pci_remove_state *prs,
-                                 int rc)
+static void pci_remove_detached(libxl__egc *egc,
+                                pci_remove_state *prs,
+                                int rc)
 {
     STATE_AO_GC(prs->aodev->ao);
     int stubdomid = 0;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:01:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:01:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56156.98070 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PL-0005FG-5X; Thu, 17 Dec 2020 21:01:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56156.98070; Thu, 17 Dec 2020 21:01:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PL-0005F7-1D; Thu, 17 Dec 2020 21:01:55 +0000
Received: by outflank-mailman (input) for mailman id 56156;
 Thu, 17 Dec 2020 21:01:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PJ-0005EA-RK
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PJ-0007tH-QZ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PJ-0006Eb-PQ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:01:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7lN6R4cj6aO/OjoyC16e9okWxS7eCUgTH2WguMM8lJo=; b=UO9Y/I/dkTxFfX/Apm6/A4g8MX
	iDhnj4RQYVdRdyfBExmp3nj1wFSMF3PNMYtYbHhCTQuJayHbv354jcp/ueO+cmWbZhk/GvH31MwZI
	UphGqjfNIf/3bTpeuieWAxZtq9H1yZG1frUsWFRmd9OquA+2iYTAynVcOBBvioLOu/zk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: remove extraneous arguments to do_pci_remove() in libxl_pci.c
Message-Id: <E1kq0PJ-0006Eb-PQ@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:01:53 +0000

commit a825ab3a6b16d216660e689b082e979dd991ca95
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:15 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove extraneous arguments to do_pci_remove() in libxl_pci.c
    
    Both 'domid' and 'pci' are available in 'pci_remove_state' so there is no
    need to also pass them as separate arguments.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index b6d3bd29b7..bcc4d2ef96 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1871,14 +1871,14 @@ static void pci_remove_stubdom_done(libxl__egc *egc,
 static void pci_remove_done(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 
-static void do_pci_remove(libxl__egc *egc, uint32_t domid,
-                          libxl_device_pci *pci, int force,
-                          pci_remove_state *prs)
+static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *assigned;
+    uint32_t domid = prs->domid;
     libxl_domain_type type = libxl__domain_type(gc, domid);
+    libxl_device_pci *pci = prs->pci;
     int rc, num;
     uint32_t domainid = domid;
 
@@ -2275,7 +2275,6 @@ static void device_pci_remove_common_next(libxl__egc *egc,
     EGC_GC;
 
     /* Convenience aliases */
-    libxl_domid domid = prs->domid;
     libxl_device_pci *const pci = prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
@@ -2293,7 +2292,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
             } else {
                 pci->vdevfn = orig_vdev;
             }
-            do_pci_remove(egc, domid, pci, prs->force, prs);
+            do_pci_remove(egc, prs);
             return;
         }
     }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56157.98072 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PV-0005HV-60; Thu, 17 Dec 2020 21:02:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56157.98072; Thu, 17 Dec 2020 21:02:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0PV-0005HM-2z; Thu, 17 Dec 2020 21:02:05 +0000
Received: by outflank-mailman (input) for mailman id 56157;
 Thu, 17 Dec 2020 21:02:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PT-0005HC-VK
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PT-0007tt-UZ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0PT-0006FT-Sw
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ImMVhH1cEt8po7iyjhqJVI2n12sG2Zy8cn4p4vjmAPs=; b=MTYYph4F/jjJd6iEJbWQqJ0dDM
	ujiKjBhomLe48Qt5adzoSmKqxACD+iSoHPNZe38uDCjzsyXhGNEwfL91MLXnNUUis3AJI/A/evhl4
	5h9rTNa49inpvmm+Y0UG2U1u+7w+W+VHVQzvUIdMjJuAo99O0PvE6U6Gbgyq3LaweVMk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: stop using aodev->device_config in libxl__device_pci_add()...
Message-Id: <E1kq0PT-0006FT-Sw@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:03 +0000

commit b5429d65e1827c4086b2195f594574abd65eb46d
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:16 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: stop using aodev->device_config in libxl__device_pci_add()...
    
    ... to hold a pointer to the device.
    
    There is already a 'pci' field in 'pci_add_state' so simply use that from
    the start. This also allows the 'pci' (#3) argument to be dropped from
    do_pci_add().
    
    NOTE: This patch also changes the type of the 'pci_domid' field in
          'pci_add_state' from 'int' to 'libxl_domid' which is more appropriate
          given what the field is used for.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index bcc4d2ef96..be2145222d 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1074,7 +1074,7 @@ typedef struct pci_add_state {
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
     libxl_device_pci *pci;
-    int pci_domid;
+    libxl_domid pci_domid;
 } pci_add_state;
 
 static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
@@ -1091,7 +1091,6 @@ static void pci_add_dm_done(libxl__egc *,
 
 static void do_pci_add(libxl__egc *egc,
                        libxl_domid domid,
-                       libxl_device_pci *pci,
                        pci_add_state *pas)
 {
     STATE_AO_GC(pas->aodev->ao);
@@ -1101,7 +1100,6 @@ static void do_pci_add(libxl__egc *egc,
     /* init pci_add_state */
     libxl__xswait_init(&pas->xswait);
     libxl__ev_qmp_init(&pas->qmp);
-    pas->pci = pci;
     pas->pci_domid = domid;
     libxl__ev_time_init(&pas->timeout);
 
@@ -1564,13 +1562,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     int stubdomid = 0;
     pci_add_state *pas;
 
-    /* Store *pci to be used by callbacks */
-    aodev->device_config = pci;
-    aodev->device_type = &libxl__pci_devtype;
-
     GCNEW(pas);
     pas->aodev = aodev;
     pas->domid = domid;
+    pas->pci = pci;
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
@@ -1624,9 +1619,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         GCNEW(pci_s);
         libxl_device_pci_init(pci_s);
         libxl_device_pci_copy(CTX, pci_s, pci);
+        pas->pci = pci_s;
         pas->callback = device_pci_add_stubdom_wait;
 
-        do_pci_add(egc, stubdomid, pci_s, pas); /* must be last */
+        do_pci_add(egc, stubdomid, pas); /* must be last */
         return;
     }
 
@@ -1681,9 +1677,8 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
     int i;
 
     /* Convenience aliases */
-    libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = aodev->device_config;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) goto out;
 
@@ -1718,7 +1713,7 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
                 pci->vdevfn = orig_vdev;
             }
             pas->callback = device_pci_add_done;
-            do_pci_add(egc, domid, pci, pas); /* must be last */
+            do_pci_add(egc, domid, pas); /* must be last */
             return;
         }
     }
@@ -1734,7 +1729,7 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = aodev->device_config;
+    libxl_device_pci *pci = pas->pci;
 
     if (rc) {
         LOGD(ERROR, domid,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56160.98093 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pf-0005LW-Kg; Thu, 17 Dec 2020 21:02:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56160.98093; Thu, 17 Dec 2020 21:02:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pf-0005LN-Gz; Thu, 17 Dec 2020 21:02:15 +0000
Received: by outflank-mailman (input) for mailman id 56160;
 Thu, 17 Dec 2020 21:02:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Pe-0005Kx-2A
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Pe-0007u0-1P
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Pe-0006GH-0f
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=EK9MERtBXMCdtjrMM7u3e3exFTR8G8ZeAXv6oh1O/sk=; b=THf4cTIX22gyuaYN1IW3elpqWI
	2/15uzJmmlGR9ccaEthkLEKO+eFQev4jlEwC3n0IO2REs8G+pxgbGN6iDnrau2LtR7BNeBvbs+Na7
	6etISyzyLrck/y2rxv9lekwHeedFdZR0dDeZfstzkFDKtw/8P+TH+9Ssd6ELzB6+paEw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: generalise 'driver_path' xenstore access functions in libxl_pci.c
Message-Id: <E1kq0Pe-0006GH-0f@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:14 +0000

commit fe91a3aadc038adbc2954e9a66e88493121a232e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:17 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: generalise 'driver_path' xenstore access functions in libxl_pci.c
    
    For the purposes of re-binding a device to its previous driver
    libxl__device_pci_assignable_add() writes the driver path into xenstore.
    This path is then read back in libxl__device_pci_assignable_remove().
    
    The functions that support this writing to and reading from xenstore are
    currently dedicated for this purpose and hence the node name 'driver_path'
    is hard-coded. This patch generalizes these utility functions and passes
    'driver_path' as an argument. Subsequent patches will invoke them to
    access other nodes.
    
    NOTE: Because functions will have a broader use (other than storing a
          driver path in lieu of pciback) the base xenstore path is also
          changed from '/libxl/pciback' to '/libxl/pci'.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 66 +++++++++++++++++++++-----------------------
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index be2145222d..78ee641e9a 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -737,48 +737,46 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-#define PCIBACK_INFO_PATH "/libxl/pciback"
+#define PCI_INFO_PATH "/libxl/pci"
 
-static void pci_assignable_driver_path_write(libxl__gc *gc,
-                                            libxl_device_pci *pci,
-                                            char *driver_path)
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
 {
-    char *path;
+    return node ?
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
+                  pci->domain, pci->bus, pci->dev, pci->func,
+                  node) :
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
+                  pci->domain, pci->bus, pci->dev, pci->func);
+}
+
+
+static void pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node, const char *val)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
 
-    path = GCSPRINTF(PCIBACK_INFO_PATH"/"PCI_BDF_XSPATH"/driver_path",
-                     pci->domain,
-                     pci->bus,
-                     pci->dev,
-                     pci->func);
-    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", driver_path) < 0 ) {
-        LOGE(WARN, "Write of %s to node %s failed.", driver_path, path);
+    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", val) < 0 ) {
+        LOGE(WARN, "Write of %s to node %s failed.", val, path);
     }
 }
 
-static char * pci_assignable_driver_path_read(libxl__gc *gc,
-                                              libxl_device_pci *pci)
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
 {
-    return libxl__xs_read(gc, XBT_NULL,
-                          GCSPRINTF(
-                           PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH "/driver_path",
-                           pci->domain,
-                           pci->bus,
-                           pci->dev,
-                           pci->func));
+    char *path = pci_info_xs_path(gc, pci, node);
+
+    return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_assignable_driver_path_remove(libxl__gc *gc,
-                                              libxl_device_pci *pci)
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+                               const char *node)
 {
+    char *path = pci_info_xs_path(gc, pci, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
-    xs_rm(ctx->xsh, XBT_NULL,
-          GCSPRINTF(PCIBACK_INFO_PATH "/" PCI_BDF_XSPATH,
-                    pci->domain,
-                    pci->bus,
-                    pci->dev,
-                    pci->func) );
+    xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
@@ -824,9 +822,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_assignable_driver_path_write(gc, pci, driver_path);
+            pci_info_xs_write(gc, pci, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_assignable_driver_path_read(gc, pci)) != NULL ) {
+                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -834,7 +832,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_assignable_driver_path_remove(gc, pci);
+        pci_info_xs_remove(gc, pci, "driver_path");
     }
 
     if ( pciback_dev_assign(gc, pci) ) {
@@ -884,7 +882,7 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     }
 
     /* Rebind if necessary */
-    driver_path = pci_assignable_driver_path_read(gc, pci);
+    driver_path = pci_info_xs_read(gc, pci, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -897,7 +895,7 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
                 return -1;
             }
 
-            pci_assignable_driver_path_remove(gc, pci);
+            pci_info_xs_remove(gc, pci, "driver_path");
         }
     } else {
         if ( rebind ) {
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56162.98096 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pp-0005On-Lq; Thu, 17 Dec 2020 21:02:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56162.98096; Thu, 17 Dec 2020 21:02:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pp-0005Oe-IZ; Thu, 17 Dec 2020 21:02:25 +0000
Received: by outflank-mailman (input) for mailman id 56162;
 Thu, 17 Dec 2020 21:02:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Po-0005OH-5F
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Po-0007u3-4U
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Po-0006Ho-3p
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hNhur+HGQaVI9Tpz8AO5A5PY4vbaAFNiD389kBTxSR0=; b=AVcCtCiSye6FWG8T6nu1N0W+Ju
	Qoc0OYyU7bqdA0vtj3qR++nvhsMhh8ypdvueUlBF8FXueZM3I6visygybMc5x33kyFG3K3iiP7xhN
	FiPXYLj0cXYINsXsqZg1Y7aRxA42M0w6b9GuyhCYotAyNWuQrNqIhOiyXsdV4oaBAodE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: remove unnecessary check from libxl__device_pci_add()
Message-Id: <E1kq0Po-0006Ho-3p@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:24 +0000

commit 4951b9ea807d4a4e5a54798d366b2ea3d6ca5060
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:18 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove unnecessary check from libxl__device_pci_add()
    
    The code currently checks explicitly whether the device is already assigned,
    but this is actually unnecessary as assigned devices do not form part of
    the list returned by libxl_device_pci_assignable_list() and hence the
    libxl_pci_assignable() test would have already failed.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 78ee641e9a..0c2ab5075d 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1555,8 +1555,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 {
     STATE_AO_GC(aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    libxl_device_pci *assigned;
-    int num_assigned, rc;
+    int rc;
     int stubdomid = 0;
     pci_add_state *pas;
 
@@ -1595,19 +1594,6 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         goto out;
     }
 
-    rc = get_all_assigned_devices(gc, &assigned, &num_assigned);
-    if ( rc ) {
-        LOGD(ERROR, domid,
-             "cannot determine if device is assigned, refusing to continue");
-        goto out;
-    }
-    if ( is_pci_in_array(assigned, num_assigned, pci->domain,
-                         pci->bus, pci->dev, pci->func) ) {
-        LOGD(ERROR, domid, "PCI device already attached to a domain");
-        rc = ERROR_FAIL;
-        goto out;
-    }
-
     libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56164.98099 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pz-0005RA-Of; Thu, 17 Dec 2020 21:02:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56164.98099; Thu, 17 Dec 2020 21:02:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Pz-0005R2-La; Thu, 17 Dec 2020 21:02:35 +0000
Received: by outflank-mailman (input) for mailman id 56164;
 Thu, 17 Dec 2020 21:02:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Py-0005Qr-8a
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Py-0007u6-7m
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Py-0006IW-6x
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nhIepNLAx0CVmg/t5jKKyEfLCC436Yf3TspH9SjU9N4=; b=VLTN2M2gP+SlryrX0okQ7pZpFd
	tIBy4E8cxI74cUfILa3/eo6sb9J/yBHC2uSOcVtFFg6y9z2SOfPpjURcOyoT84X5ifyQvZ+QEuYay
	YVQKRLObIenzR0+8jHWsBBXyM4Ms0lUBdYh3EVFHquguJWxoJHtBv4sB2FxhLgGX8ziI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: remove get_all_assigned_devices() from libxl_pci.c
Message-Id: <E1kq0Py-0006IW-6x@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:34 +0000

commit f8cfb85719b600f3f87a1a3931f292f4335dcce4
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:19 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: remove get_all_assigned_devices() from libxl_pci.c
    
    Use of this function is a very inefficient way to check whether a device
    has already been assigned.
    
    This patch adds code that saves the domain id in xenstore at the point of
    assignment, and removes it again when the device id de-assigned (or the
    domain is destroyed). It is then straightforward to check whether a device
    has been assigned by checking whether a device has a saved domain id.
    
    NOTE: To facilitate the xenstore check it is necessary to move the
          pci_info_xs_read() earlier in libxl_pci.c. To keep related functions
          together, the rest of the pci_info_xs_XXX() functions are moved too.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 149 ++++++++++++++++---------------------------
 1 file changed, 55 insertions(+), 94 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 0c2ab5075d..37a6ec9eb4 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -336,50 +336,6 @@ retry_transaction2:
     return 0;
 }
 
-static int get_all_assigned_devices(libxl__gc *gc, libxl_device_pci **list, int *num)
-{
-    char **domlist;
-    unsigned int nd = 0, i;
-
-    *list = NULL;
-    *num = 0;
-
-    domlist = libxl__xs_directory(gc, XBT_NULL, "/local/domain", &nd);
-    for(i = 0; i < nd; i++) {
-        char *path, *num_devs;
-
-        path = GCSPRINTF("/local/domain/0/backend/%s/%s/0/num_devs",
-                         libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI),
-                         domlist[i]);
-        num_devs = libxl__xs_read(gc, XBT_NULL, path);
-        if ( num_devs ) {
-            int ndev = atoi(num_devs), j;
-            char *devpath, *bdf;
-
-            for(j = 0; j < ndev; j++) {
-                devpath = GCSPRINTF("/local/domain/0/backend/%s/%s/0/dev-%u",
-                                    libxl__device_kind_to_string(LIBXL__DEVICE_KIND_PCI),
-                                    domlist[i], j);
-                bdf = libxl__xs_read(gc, XBT_NULL, devpath);
-                if ( bdf ) {
-                    unsigned dom, bus, dev, func;
-                    if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
-                        continue;
-
-                    *list = realloc(*list, sizeof(libxl_device_pci) * ((*num) + 1));
-                    if (*list == NULL)
-                        return ERROR_NOMEM;
-                    pci_struct_fill(*list + *num, dom, bus, dev, func, 0);
-                    (*num)++;
-                }
-            }
-        }
-    }
-    libxl__ptr_add(gc, *list);
-
-    return 0;
-}
-
 static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
                            int dom, int bus, int dev, int func)
 {
@@ -427,19 +383,58 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
     return 0;
 }
 
+#define PCI_INFO_PATH "/libxl/pci"
+
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
+{
+    return node ?
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
+                  pci->domain, pci->bus, pci->dev, pci->func,
+                  node) :
+        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
+                  pci->domain, pci->bus, pci->dev, pci->func);
+}
+
+
+static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node, const char *val)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+    int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
+
+    if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
+
+    return rc;
+}
+
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+                              const char *node)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+
+    return libxl__xs_read(gc, XBT_NULL, path);
+}
+
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+                               const char *node)
+{
+    char *path = pci_info_xs_path(gc, pci, node);
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+
+    /* Remove the xenstore entry */
+    xs_rm(ctx->xsh, XBT_NULL, path);
+}
+
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcis = NULL, *new, *assigned;
+    libxl_device_pci *pcis = NULL, *new;
     struct dirent *de;
     DIR *dir;
-    int r, num_assigned;
 
     *num = 0;
 
-    r = get_all_assigned_devices(gc, &assigned, &num_assigned);
-    if (r) goto out;
-
     dir = opendir(SYSFS_PCIBACK_DRIVER);
     if (NULL == dir) {
         if (errno == ENOENT) {
@@ -455,9 +450,6 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        if (is_pci_in_array(assigned, num_assigned, dom, bus, dev, func))
-            continue;
-
         new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
@@ -467,6 +459,10 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 
         memset(new, 0, sizeof(*new));
         pci_struct_fill(new, dom, bus, dev, func, 0);
+
+        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
+            continue;
+
         (*num)++;
     }
 
@@ -737,48 +733,6 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-#define PCI_INFO_PATH "/libxl/pci"
-
-static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node)
-{
-    return node ?
-        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->domain, pci->bus, pci->dev, pci->func,
-                  node) :
-        GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->domain, pci->bus, pci->dev, pci->func);
-}
-
-
-static void pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node, const char *val)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-
-    if ( libxl__xs_printf(gc, XBT_NULL, path, "%s", val) < 0 ) {
-        LOGE(WARN, "Write of %s to node %s failed.", val, path);
-    }
-}
-
-static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
-                              const char *node)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-
-    return libxl__xs_read(gc, XBT_NULL, path);
-}
-
-static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
-                               const char *node)
-{
-    char *path = pci_info_xs_path(gc, pci, node);
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-
-    /* Remove the xenstore entry */
-    xs_rm(ctx->xsh, XBT_NULL, path);
-}
-
 static int libxl__device_pci_assignable_add(libxl__gc *gc,
                                             libxl_device_pci *pci,
                                             int rebind)
@@ -1594,6 +1548,9 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         goto out;
     }
 
+    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
+    if (rc) goto out;
+
     libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
@@ -1721,6 +1678,7 @@ static void device_pci_add_done(libxl__egc *egc,
              "PCI device %x:%x:%x.%x (rc %d)",
              pci->domain, pci->bus, pci->dev, pci->func,
              rc);
+        pci_info_xs_remove(gc, pci, "domid");
     }
     aodev->rc = rc;
     aodev->callback(egc, aodev);
@@ -2282,6 +2240,9 @@ out:
     libxl__xswait_stop(gc, &prs->xswait);
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
+
+    if (!rc) pci_info_xs_remove(gc, pci, "domid");
+
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56165.98104 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Q9-0005Sy-Qk; Thu, 17 Dec 2020 21:02:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56165.98104; Thu, 17 Dec 2020 21:02:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Q9-0005Sp-N9; Thu, 17 Dec 2020 21:02:45 +0000
Received: by outflank-mailman (input) for mailman id 56165;
 Thu, 17 Dec 2020 21:02:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Q8-0005Sb-CZ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Q8-0007uA-BM
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Q8-0006JB-AL
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+vBthCXyuTmdoA2xRwJu//J/IF4ab2zuofZ6iBQQ9ag=; b=G8rNh4myIPLuIgcS3u5cjaQiNd
	45UzRHlcsRcJaJEK02bgGylbds6TeZmKBLHiXeBYxMXvaN0dEEmnxKzZUuxGH7W1snyCMdhQ+++Hw
	QMvmSk/pVjn2NEK38GYxfs3qP6nn3i6GxmqApIJHSRUBf3haDhBZoNN3KDQ/Fzs6liAU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: make sure callers of libxl_device_pci_list() free the list after use
Message-Id: <E1kq0Q8-0006JB-AL@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:44 +0000

commit 7499b22ba1f68237c201da8534706dbe430987d5
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:20 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: make sure callers of libxl_device_pci_list() free the list after use
    
    A previous patch introduced libxl_device_pci_list_free() which should be used
    by callers of libxl_device_pci_list() to properly dispose of the exported
    'libxl_device_pci' types and the free the memory holding them. Whilst all
    current callers do ensure the memory is freed, only the code in xl's
    pcilist() function actually calls libxl_device_pci_dispose(). As it stands
    this laxity does not lead to any memory leaks, but the simple addition of
    .e.g. a 'string' into the idl definition of 'libxl_device_pci' would lead
    to leaks.
    
    This patch makes sure all callers of libxl_device_pci_list() can call
    libxl_device_pci_list_free() by keeping copies of 'libxl_device_pci'
    structures inline in 'pci_add_state' and 'pci_remove_state' (and also making
    sure these are properly disposed at the end of the operations) rather
    than keeping pointers to the structures returned by libxl_device_pci_list().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 68 ++++++++++++++++++++++++--------------------
 tools/xl/xl_pci.c            |  3 +-
 2 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 37a6ec9eb4..c555f3ed29 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1025,7 +1025,7 @@ typedef struct pci_add_state {
     libxl__xswait_state xswait;
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
-    libxl_device_pci *pci;
+    libxl_device_pci pci;
     libxl_domid pci_domid;
 } pci_add_state;
 
@@ -1097,7 +1097,7 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1118,7 +1118,7 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
     libxl__ev_qmp *const qmp = &pas->qmp;
 
     rc = libxl__ev_time_register_rel(ao, &pas->timeout,
@@ -1199,7 +1199,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
     int dev_slot, dev_func;
 
     /* Convenience aliases */
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) goto out;
 
@@ -1300,7 +1300,7 @@ static void pci_add_dm_done(libxl__egc *egc,
 
     /* Convenience aliases */
     bool starting = pas->starting;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
     bool hvm = libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM;
 
     libxl__ev_qmp_dispose(gc, &pas->qmp);
@@ -1516,7 +1516,10 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     GCNEW(pas);
     pas->aodev = aodev;
     pas->domid = domid;
-    pas->pci = pci;
+
+    libxl_device_pci_copy(CTX, &pas->pci, pci);
+    pci = &pas->pci;
+
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
@@ -1555,12 +1558,6 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
-        libxl_device_pci *pci_s;
-
-        GCNEW(pci_s);
-        libxl_device_pci_init(pci_s);
-        libxl_device_pci_copy(CTX, pci_s, pci);
-        pas->pci = pci_s;
         pas->callback = device_pci_add_stubdom_wait;
 
         do_pci_add(egc, stubdomid, pas); /* must be last */
@@ -1619,7 +1616,7 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) goto out;
 
@@ -1670,7 +1667,7 @@ static void device_pci_add_done(libxl__egc *egc,
     EGC_GC;
     libxl__ao_device *aodev = pas->aodev;
     libxl_domid domid = pas->domid;
-    libxl_device_pci *pci = pas->pci;
+    libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
         LOGD(ERROR, domid,
@@ -1680,6 +1677,7 @@ static void device_pci_add_done(libxl__egc *egc,
              rc);
         pci_info_xs_remove(gc, pci, "domid");
     }
+    libxl_device_pci_dispose(pci);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
@@ -1770,7 +1768,7 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
 typedef struct pci_remove_state {
     libxl__ao_device *aodev;
     libxl_domid domid;
-    libxl_device_pci *pci;
+    libxl_device_pci pci;
     bool force;
     bool hvm;
     unsigned int orig_vdev;
@@ -1812,23 +1810,26 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
 {
     STATE_AO_GC(prs->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    libxl_device_pci *assigned;
+    libxl_device_pci *pcis;
+    bool attached;
     uint32_t domid = prs->domid;
     libxl_domain_type type = libxl__domain_type(gc, domid);
-    libxl_device_pci *pci = prs->pci;
+    libxl_device_pci *pci = &prs->pci;
     int rc, num;
     uint32_t domainid = domid;
 
-    assigned = libxl_device_pci_list(ctx, domid, &num);
-    if (assigned == NULL) {
+    pcis = libxl_device_pci_list(ctx, domid, &num);
+    if (!pcis) {
         rc = ERROR_FAIL;
         goto out_fail;
     }
-    libxl__ptr_add(gc, assigned);
+
+    attached = is_pci_in_array(pcis, num, pci->domain,
+                               pci->bus, pci->dev, pci->func);
+    libxl_device_pci_list_free(pcis, num);
 
     rc = ERROR_INVAL;
-    if ( !is_pci_in_array(assigned, num, pci->domain,
-                          pci->bus, pci->dev, pci->func) ) {
+    if (!attached) {
         LOGD(ERROR, domainid, "PCI device not attached to this domain");
         goto out_fail;
     }
@@ -1928,7 +1929,7 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     rc = check_qemu_running(gc, domid, xswa, rc, state);
     if (rc == ERROR_NOT_READY)
@@ -1950,7 +1951,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     int rc;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     rc = libxl__ev_time_register_rel(ao, &prs->timeout,
                                      pci_remove_timeout,
@@ -2020,7 +2021,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
 
     /* Convenience aliases */
     libxl__ao *const ao = prs->aodev->ao;
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     if (rc) goto out;
 
@@ -2075,7 +2076,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     pci_remove_state *prs = CONTAINER_OF(ev, *prs, timeout);
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
          PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
@@ -2096,7 +2097,7 @@ static void pci_remove_detached(libxl__egc *egc,
     bool isstubdom;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
     libxl_domid domid = prs->domid;
 
     /* Cleaning QMP states ASAP */
@@ -2159,7 +2160,7 @@ static void pci_remove_done(libxl__egc *egc,
 
     if (rc) goto out;
 
-    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pci);
+    libxl__device_pci_remove_xenstore(gc, prs->domid, &prs->pci);
 out:
     device_pci_remove_common_next(egc, prs, rc);
 }
@@ -2177,7 +2178,10 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     GCNEW(prs);
     prs->aodev = aodev;
     prs->domid = domid;
-    prs->pci = pci;
+
+    libxl_device_pci_copy(CTX, &prs->pci, pci);
+    pci = &prs->pci;
+
     prs->force = force;
     libxl__xswait_init(&prs->xswait);
     libxl__ev_qmp_init(&prs->qmp);
@@ -2212,7 +2216,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
     EGC_GC;
 
     /* Convenience aliases */
-    libxl_device_pci *const pci = prs->pci;
+    libxl_device_pci *const pci = &prs->pci;
     libxl__ao_device *const aodev = prs->aodev;
     const unsigned int pfunc_mask = prs->pfunc_mask;
     const unsigned int orig_vdev = prs->orig_vdev;
@@ -2243,6 +2247,7 @@ out:
 
     if (!rc) pci_info_xs_remove(gc, pci, "domid");
 
+    libxl_device_pci_dispose(pci);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
@@ -2357,7 +2362,6 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
     pcis = libxl_device_pci_list(CTX, domid, &num);
     if ( pcis == NULL )
         return;
-    libxl__ptr_add(gc, pcis);
 
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
@@ -2368,6 +2372,8 @@ void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
         libxl__device_pci_remove_common(egc, domid, pcis + i, true,
                                         aodev);
     }
+
+    libxl_device_pci_list_free(pcis, num);
 }
 
 int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid,
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 34fcf5a4fa..7c0f102ac7 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -35,9 +35,8 @@ static void pcilist(uint32_t domid)
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
                pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
-        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcis);
+    libxl_device_pci_list_free(pcis, num);
 }
 
 int main_pcilist(int argc, char **argv)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:02:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:02:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56168.98108 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0QJ-0005UJ-Rf; Thu, 17 Dec 2020 21:02:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56168.98108; Thu, 17 Dec 2020 21:02:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0QJ-0005UB-Om; Thu, 17 Dec 2020 21:02:55 +0000
Received: by outflank-mailman (input) for mailman id 56168;
 Thu, 17 Dec 2020 21:02:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QI-0005U4-FS
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QI-0007uG-Ej
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QI-0006KD-Du
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:02:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=pZ2YrVIonBlqHhxJ1RloYHQt2ZFxj7ZNjUbZj2MPWzc=; b=ndO378nM1Z/Uvd5a+OBvyYDDv9
	H7BS80PM8TW3beKjw35vPcGXMDL4vspI6eVBTktwGzU5rfG/B0X6nlID7X5MfzuoH9gmRXwzYGEcF
	kpeHkvKFO8wl186+Kadr3Dv+lIevp7Ars7DU9CjMV4DRXn8Db1AtkbBWYWFjjCAA0QRM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: add libxl_device_pci_assignable_list_free()...
Message-Id: <E1kq0QI-0006KD-Du@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:02:54 +0000

commit c00da823550d0ff63d99b1b48effd6728bee156e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:21 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: add libxl_device_pci_assignable_list_free()...
    
    ... to be used by callers of libxl_device_pci_assignable_list().
    
    Currently there is no API for callers of libxl_device_pci_assignable_list()
    to free the list. The xl function pciassignable_list() calls
    libxl_device_pci_dispose() on each element of the returned list, but
    libxl_pci_assignable() in libxl_pci.c does not. Neither does the implementation
    of libxl_device_pci_assignable_list() call libxl_device_pci_init().
    
    This patch adds the new API function, makes sure it is used everywhere and
    also modifies libxl_device_pci_assignable_list() to initialize list
    entries rather than just zeroing them.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h                |  7 +++++++
 tools/libs/light/libxl_pci.c         | 14 ++++++++++++--
 tools/ocaml/libs/xl/xenlight_stubs.c |  3 +--
 tools/xl/xl_pci.c                    |  3 +--
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index bb7fc893fc..3433c950f9 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -457,6 +457,12 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_LIST_FREE 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE indicates that the
+ * libxl_device_pci_assignable_list_free() function is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2369,6 +2375,7 @@ int libxl_device_events_handler(libxl_ctx *ctx,
 int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
 libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
 int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str);
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index c555f3ed29..2a594e4328 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -457,7 +457,7 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         pcis = new;
         new = pcis + *num;
 
-        memset(new, 0, sizeof(*new));
+        libxl_device_pci_init(new);
         pci_struct_fill(new, dom, bus, dev, func, 0);
 
         if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
@@ -472,6 +472,16 @@ out:
     return pcis;
 }
 
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+{
+    int i;
+
+    for (i = 0; i < num; i++)
+        libxl_device_pci_dispose(&list[i]);
+
+    free(list);
+}
+
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
 static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
@@ -1490,7 +1500,7 @@ static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
             pcis[i].func == pci->func)
             break;
     }
-    free(pcis);
+    libxl_device_pci_assignable_list_free(pcis, num);
     return i != num;
 }
 
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c b/tools/ocaml/libs/xl/xenlight_stubs.c
index 1181971da4..352a00134d 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -894,9 +894,8 @@ value stub_xl_device_pci_assignable_list(value ctx)
 		Field(list, 1) = temp;
 		temp = list;
 		Store_field(list, 0, Val_device_pci(&c_list[i]));
-		libxl_device_pci_dispose(&c_list[i]);
 	}
-	free(c_list);
+	libxl_device_pci_assignable_list_free(c_list, nb);
 
 	CAMLreturn(list);
 }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 7c0f102ac7..f71498cbb5 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -164,9 +164,8 @@ static void pciassignable_list(void)
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
                pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
-        libxl_device_pci_dispose(&pcis[i]);
     }
-    free(pcis);
+    libxl_device_pci_assignable_list_free(pcis, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56169.98112 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0QT-0005W5-Ti; Thu, 17 Dec 2020 21:03:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56169.98112; Thu, 17 Dec 2020 21:03:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0QT-0005Vx-QT; Thu, 17 Dec 2020 21:03:05 +0000
Received: by outflank-mailman (input) for mailman id 56169;
 Thu, 17 Dec 2020 21:03:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QS-0005Vo-Ia
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QS-0007uw-Ht
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0QS-0006LV-HC
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wxC+WGskgkMU9bjh4UMkVtQIyyZVHzHp75jGHnJx8sc=; b=ZYrQKxaSILSWy3S/8fkgMMWJ9w
	GWxWaquonIvp62nKwrbD8xcDKphhcqU8lt4Dq65je/1QGeB3imwBcg1ks50O4BP/+hX8BHekvgjYv
	4hwzbyA5ju0w/W8G1mfrH7rYwCy4ZBLPGsoPYrgkC1/Advcfv7KZsC/2JX1eeTbaJWLI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: use COMPARE_PCI() macro is_pci_in_array()...
Message-Id: <E1kq0QS-0006LV-HC@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:04 +0000

commit 413fd4e4e958081dea06dcad37c1526f7e846732
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:22 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: use COMPARE_PCI() macro is_pci_in_array()...
    
    ... rather than an open-coded equivalent.
    
    This patch tidies up the is_pci_in_array() function, making it take a single
    'libxl_device_pci' argument rather than separate domain, bus, device and
    function arguments. The already-available COMPARE_PCI() macro can then be
    used and it is also modified to return 'bool' rather than 'int'.
    
    The patch also modifies libxl_pci_assignable() to use is_pci_in_array() rather
    than a separate open-coded equivalent, and also modifies it to return a
    'bool' rather than an 'int'.
    
    NOTE: The COMPARE_PCI() macro is also fixed to include the 'domain' in its
          comparison, which should always have been the case.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_internal.h |  7 ++++---
 tools/libs/light/libxl_pci.c      | 38 +++++++++++++-------------------------
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index d0c23def3c..c79523ba92 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,9 +4746,10 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_PCI(a, b) ((a)->func == (b)->func &&    \
-                           (a)->bus == (b)->bus &&      \
-                           (a)->dev == (b)->dev)
+#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
+                           (a)->bus == (b)->bus &&       \
+                           (a)->dev == (b)->dev &&       \
+                           (a)->func == (b)->func)
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 2a594e4328..74c2196ae3 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -336,24 +336,17 @@ retry_transaction2:
     return 0;
 }
 
-static int is_pci_in_array(libxl_device_pci *assigned, int num_assigned,
-                           int dom, int bus, int dev, int func)
+static bool is_pci_in_array(libxl_device_pci *pcis, int num,
+                            libxl_device_pci *pci)
 {
     int i;
 
-    for(i = 0; i < num_assigned; i++) {
-        if ( assigned[i].domain != dom )
-            continue;
-        if ( assigned[i].bus != bus )
-            continue;
-        if ( assigned[i].dev != dev )
-            continue;
-        if ( assigned[i].func != func )
-            continue;
-        return 1;
+    for (i = 0; i < num; i++) {
+        if (COMPARE_PCI(pci, &pcis[i]))
+            break;
     }
 
-    return 0;
+    return i < num;
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
@@ -1487,21 +1480,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static int libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
+static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
     libxl_device_pci *pcis;
-    int num, i;
+    int num;
+    bool assignable;
 
     pcis = libxl_device_pci_assignable_list(ctx, &num);
-    for (i = 0; i < num; i++) {
-        if (pcis[i].domain == pci->domain &&
-            pcis[i].bus == pci->bus &&
-            pcis[i].dev == pci->dev &&
-            pcis[i].func == pci->func)
-            break;
-    }
+    assignable = is_pci_in_array(pcis, num, pci);
     libxl_device_pci_assignable_list_free(pcis, num);
-    return i != num;
+
+    return assignable;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1834,8 +1823,7 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         goto out_fail;
     }
 
-    attached = is_pci_in_array(pcis, num, pci->domain,
-                               pci->bus, pci->dev, pci->func);
+    attached = is_pci_in_array(pcis, num, pci);
     libxl_device_pci_list_free(pcis, num);
 
     rc = ERROR_INVAL;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56170.98115 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qe-0005Xd-1C; Thu, 17 Dec 2020 21:03:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56170.98115; Thu, 17 Dec 2020 21:03:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qd-0005XW-UW; Thu, 17 Dec 2020 21:03:15 +0000
Received: by outflank-mailman (input) for mailman id 56170;
 Thu, 17 Dec 2020 21:03:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qc-0005XK-Lg
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qc-0007v6-Kz
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qc-0006MD-KA
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OCZ2Al7BdmOf1P1c0XUi24yQpc4i+zIO6NW36P0DBhE=; b=aig6Uq35zwNfF1nqvkuozbGYNi
	fGrs0I+xixuY9BK9jlBkl51wqinI8owzkUtp7Uq+0gE4+AdmOygQFHRoKbPMAUd4Pytzln6NmueIJ
	jhEo1kiNjZt+TPMCSqX0rn67KHCkjHl6EWhK+n1Q0gaxjF2N+MfajzfKz/G/0Y90iuI4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs/man: extract documentation of PCI_SPEC_STRING from the xl.cfg manpage...
Message-Id: <E1kq0Qc-0006MD-KA@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:14 +0000

commit 581abb66a9ee5de403c97b2520960f65a878a0ff
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:23 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: extract documentation of PCI_SPEC_STRING from the xl.cfg manpage...
    
    ... and put it into a new xl-pci-configuration(5) manpage, akin to the
    xl-network-configration(5) and xl-disk-configuration(5) manpages.
    
    This patch moves the content of the section verbatim. A subsequent patch
    will improve the documentation, once it is in its new location.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 78 +++++++++++++++++++++++++++++++++++++
 docs/man/xl.cfg.5.pod.in            | 68 +-------------------------------
 2 files changed, 79 insertions(+), 67 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
new file mode 100644
index 0000000000..72a27bd95d
--- /dev/null
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -0,0 +1,78 @@
+=encoding utf8
+
+=head1 NAME
+
+xl-pci-configuration - XL PCI Configuration Syntax
+
+=head1 SYNTAX
+
+This document specifies the format for B<PCI_SPEC_STRING> which is used by
+the L<xl.cfg(5)> pci configuration option, and related L<xl(1)> commands.
+
+Each B<PCI_SPEC_STRING> has the form of
+B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
+
+=over 4
+
+=item B<[DDDD:]BB:DD.F>
+
+Identifies the PCI device from the host perspective in the domain
+(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
+the same scheme as used in the output of B<lspci(1)> for the device in
+question.
+
+Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
+is zero and it is optional here also. You may specify the function
+(B<F>) as B<*> to indicate all functions.
+
+=item B<@VSLOT>
+
+Specifies the virtual slot where the guest will see this
+device. This is equivalent to the B<DD> which the guest sees. In a
+guest B<DDDD> and B<BB> are C<0000:00>.
+
+=item B<permissive=BOOLEAN>
+
+By default pciback only allows PV guests to write "known safe" values
+into PCI configuration space, likewise QEMU (both qemu-xen and
+qemu-xen-traditional) imposes the same constraint on HVM guests.
+However, many devices require writes to other areas of the configuration space
+in order to operate properly.  This option tells the backend (pciback or QEMU)
+to allow all writes to the PCI configuration space of this device by this
+domain.
+
+B<This option should be enabled with caution:> it gives the guest much
+more control over the device, which may have security or stability
+implications.  It is recommended to only enable this option for
+trusted VMs under administrator's control.
+
+=item B<msitranslate=BOOLEAN>
+
+Specifies that MSI-INTx translation should be turned on for the PCI
+device. When enabled, MSI-INTx translation will always enable MSI on
+the PCI device regardless of whether the guest uses INTx or MSI. Some
+device drivers, such as NVIDIA's, detect an inconsistency and do not
+function when this option is enabled. Therefore the default is false (0).
+
+=item B<seize=BOOLEAN>
+
+Tells B<xl> to automatically attempt to re-assign a device to
+pciback if it is not already assigned.
+
+B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
+system device, such as a network or a disk controller being used by
+dom0 without confirmation.  Please use with care.
+
+=item B<power_mgmt=BOOLEAN>
+
+B<(HVM only)> Specifies that the VM should be able to program the
+D0-D3hot power management states for the PCI device. The default is false (0).
+
+=item B<rdm_policy=STRING>
+
+B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
+option but just specific to a given device. The default is "relaxed".
+
+Note: this would override global B<rdm> option.
+
+=back
diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 12201a7e54..c8e017f950 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -1101,73 +1101,7 @@ option is valid only when the B<controller> option is specified.
 =item B<pci=[ "PCI_SPEC_STRING", "PCI_SPEC_STRING", ...]>
 
 Specifies the host PCI devices to passthrough to this guest.
-Each B<PCI_SPEC_STRING> has the form of
-B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
-
-=over 4
-
-=item B<[DDDD:]BB:DD.F>
-
-Identifies the PCI device from the host perspective in the domain
-(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
-the same scheme as used in the output of B<lspci(1)> for the device in
-question.
-
-Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
-is zero and it is optional here also. You may specify the function
-(B<F>) as B<*> to indicate all functions.
-
-=item B<@VSLOT>
-
-Specifies the virtual slot where the guest will see this
-device. This is equivalent to the B<DD> which the guest sees. In a
-guest B<DDDD> and B<BB> are C<0000:00>.
-
-=item B<permissive=BOOLEAN>
-
-By default pciback only allows PV guests to write "known safe" values
-into PCI configuration space, likewise QEMU (both qemu-xen and
-qemu-xen-traditional) imposes the same constraint on HVM guests.
-However, many devices require writes to other areas of the configuration space
-in order to operate properly.  This option tells the backend (pciback or QEMU)
-to allow all writes to the PCI configuration space of this device by this
-domain.
-
-B<This option should be enabled with caution:> it gives the guest much
-more control over the device, which may have security or stability
-implications.  It is recommended to only enable this option for
-trusted VMs under administrator's control.
-
-=item B<msitranslate=BOOLEAN>
-
-Specifies that MSI-INTx translation should be turned on for the PCI
-device. When enabled, MSI-INTx translation will always enable MSI on
-the PCI device regardless of whether the guest uses INTx or MSI. Some
-device drivers, such as NVIDIA's, detect an inconsistency and do not
-function when this option is enabled. Therefore the default is false (0).
-
-=item B<seize=BOOLEAN>
-
-Tells B<xl> to automatically attempt to re-assign a device to
-pciback if it is not already assigned.
-
-B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
-system device, such as a network or a disk controller being used by
-dom0 without confirmation.  Please use with care.
-
-=item B<power_mgmt=BOOLEAN>
-
-B<(HVM only)> Specifies that the VM should be able to program the
-D0-D3hot power management states for the PCI device. The default is false (0).
-
-=item B<rdm_policy=STRING>
-
-B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
-option but just specific to a given device. The default is "relaxed".
-
-Note: this would override global B<rdm> option.
-
-=back
+See L<xl-pci-configuration(5)> for more details.
 
 =item B<pci_permissive=BOOLEAN>
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56171.98120 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qo-0005Yx-3J; Thu, 17 Dec 2020 21:03:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56171.98120; Thu, 17 Dec 2020 21:03:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qo-0005Yo-01; Thu, 17 Dec 2020 21:03:26 +0000
Received: by outflank-mailman (input) for mailman id 56171;
 Thu, 17 Dec 2020 21:03:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qm-0005Yd-PA
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qm-0007vH-OS
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qm-0006N5-N6
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ZwtXMfdPT4+PJcpCmonKMNj1jPwscJ9o156wvCdQ1kk=; b=wm71NpyluQvh1OwC+Qm1cH0CFU
	sLoaX8d94ARq2BIJe4li3nqFdaM3jRVm5d3fdBs5i2oSplqa0W16wYuoCr/Nr+yo9IGiWosFXDfj9
	mQwVzZWBp9Dd3G60FYeuFpA9cf6qduEIE1NgJ51KS0rfXtaPqc6ViQe1UZpihQTWenK8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs/man: improve documentation of PCI_SPEC_STRING...
Message-Id: <E1kq0Qm-0006N5-N6@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:24 +0000

commit 3085930e2f55a51d33a664072c3045aa2cc94445
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:24 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: improve documentation of PCI_SPEC_STRING...
    
    ... and prepare for adding support for non-positional parsing of 'bdf' and
    'vslot' in a subsequent patch.
    
    Also document 'BDF' as a first-class parameter type and fix the documentation
    to state that the default value of 'rdm_policy' is actually 'strict', not
    'relaxed', as can be seen in libxl__device_pci_setdefault().
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 177 ++++++++++++++++++++++++++++++------
 1 file changed, 148 insertions(+), 29 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index 72a27bd95d..4dd73bc498 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -6,32 +6,105 @@ xl-pci-configuration - XL PCI Configuration Syntax
 
 =head1 SYNTAX
 
-This document specifies the format for B<PCI_SPEC_STRING> which is used by
-the L<xl.cfg(5)> pci configuration option, and related L<xl(1)> commands.
+This document specifies the format for B<BDF> and B<PCI_SPEC_STRING> which are
+used by the L<xl.cfg(5)> pci configuration option, and related L<xl(1)>
+commands.
 
-Each B<PCI_SPEC_STRING> has the form of
-B<[DDDD:]BB:DD.F[@VSLOT],KEY=VALUE,KEY=VALUE,...> where:
+A B<BDF> has the following form:
+
+    [DDDD:]BB:SS.F
+
+B<DDDD> is the domain number, B<BB> is the bus number, B<SS> is the device (or
+slot) number, and B<F> is the function number. This is the same scheme as
+used in the output of L<lspci(1)> for the device in question. By default
+L<lspci(1)> will omit the domain (B<DDDD>) if it is zero and hence a zero
+value for domain may also be omitted when specifying a B<BDF>.
+
+Each B<PCI_SPEC_STRING> has the one of the forms:
+
+=over 4
+
+    [<bdf>[@<vslot>,][<key>=<value>,]*
+    [<key>=<value>,]*
+
+=back
+
+For example, these strings are equivalent:
 
 =over 4
 
-=item B<[DDDD:]BB:DD.F>
+    36:00.0@20,seize=1
+    36:00.0,vslot=20,seize=1
+    bdf=36:00.0,vslot=20,seize=1
 
-Identifies the PCI device from the host perspective in the domain
-(B<DDDD>), Bus (B<BB>), Device (B<DD>) and Function (B<F>) syntax. This is
-the same scheme as used in the output of B<lspci(1)> for the device in
-question.
+=back
+
+More formally, the string is a series of comma-separated keyword/value
+pairs, flags and positional parameters.  Parameters which are not bare
+keywords and which do not contain "=" symbols are assigned to the
+positional parameters, in the order specified below.  The positional
+parameters may also be specified by name.
+
+Each parameter may be specified at most once, either as a positional
+parameter or a named parameter.  Default values apply if the parameter
+is not specified, or if it is specified with an empty value (whether
+positionally or explicitly).
+
+B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
+B<bdf> will be ignored.
+
+=head1 Positional Parameters
+
+=over 4
+
+=item B<bdf>=I<BDF>
+
+=over 4
 
-Note: by default B<lspci(1)> will omit the domain (B<DDDD>) if it
-is zero and it is optional here also. You may specify the function
-(B<F>) as B<*> to indicate all functions.
+=item Description
 
-=item B<@VSLOT>
+This identifies the PCI device from the host perspective.
 
-Specifies the virtual slot where the guest will see this
-device. This is equivalent to the B<DD> which the guest sees. In a
-guest B<DDDD> and B<BB> are C<0000:00>.
+In the context of a B<PCI_SPEC_STRING> you may specify the function (B<F>) as
+B<*> to indicate all functions of a multi-function device.
 
-=item B<permissive=BOOLEAN>
+=item Default Value
+
+None. This parameter is mandatory as it identifies the device.
+
+=back
+
+=item B<vslot>=I<NUMBER>
+
+=over 4
+
+=item Description
+
+Specifies the virtual slot (device) number where the guest will see this
+device. For example, running L<lspci(1)> in a Linux guest where B<vslot>
+was specified as C<8> would identify the device as C<00:08.0>. Virtual domain
+and bus numbers are always 0.
+
+B<NOTE:> This parameter is always parsed as a hexidecimal value.
+
+=item Default Value
+
+None. This parameter is not mandatory. An available B<vslot> will be selected
+if this parameter is not specified.
+
+=back
+
+=back
+
+=head1 Other Parameters and Flags
+
+=over 4
+
+=item B<permissive>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 By default pciback only allows PV guests to write "known safe" values
 into PCI configuration space, likewise QEMU (both qemu-xen and
@@ -46,33 +119,79 @@ more control over the device, which may have security or stability
 implications.  It is recommended to only enable this option for
 trusted VMs under administrator's control.
 
-=item B<msitranslate=BOOLEAN>
+=item Default Value
+
+0
+
+=back
+
+=item B<msitranslate>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 Specifies that MSI-INTx translation should be turned on for the PCI
 device. When enabled, MSI-INTx translation will always enable MSI on
-the PCI device regardless of whether the guest uses INTx or MSI. Some
-device drivers, such as NVIDIA's, detect an inconsistency and do not
+the PCI device regardless of whether the guest uses INTx or MSI.
+
+=item Default Value
+
+Some device drivers, such as NVIDIA's, detect an inconsistency and do not
 function when this option is enabled. Therefore the default is false (0).
 
-=item B<seize=BOOLEAN>
+=back
+
+=item B<seize>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
-Tells B<xl> to automatically attempt to re-assign a device to
-pciback if it is not already assigned.
+Tells L<xl(1)> to automatically attempt to make the device assignable to
+guests if that has not already been done by the B<pci-assignable-add>
+command.
 
-B<WARNING:> If you set this option, B<xl> will gladly re-assign a critical
+B<WARNING:> If you set this option, L<xl> will gladly re-assign a critical
 system device, such as a network or a disk controller being used by
 dom0 without confirmation.  Please use with care.
 
-=item B<power_mgmt=BOOLEAN>
+=item Default Value
+
+0
+
+=back
+
+=item B<power_mgmt>=I<BOOLEAN>
+
+=over 4
+
+=item Description
 
 B<(HVM only)> Specifies that the VM should be able to program the
-D0-D3hot power management states for the PCI device. The default is false (0).
+D0-D3hot power management states for the PCI device.
+
+=item Default Value
+
+0
 
-=item B<rdm_policy=STRING>
+=back
+
+=item B<rdm_policy>=I<STRING>
+
+=over 4
+
+=item Description
 
 B<(HVM/x86 only)> This is the same as the policy setting inside the B<rdm>
-option but just specific to a given device. The default is "relaxed".
+option in L<xl.cfg(5)> but just specific to a given device.
 
-Note: this would override global B<rdm> option.
+B<NOTE>: This overrides the global B<rdm> option.
+
+=item Default Value
+
+"strict"
+
+=back
 
 =back
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56172.98124 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qy-0005aO-4i; Thu, 17 Dec 2020 21:03:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56172.98124; Thu, 17 Dec 2020 21:03:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Qy-0005aG-1Y; Thu, 17 Dec 2020 21:03:36 +0000
Received: by outflank-mailman (input) for mailman id 56172;
 Thu, 17 Dec 2020 21:03:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qw-0005a5-S9
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qw-0007vP-RV
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Qw-0006Nt-Ql
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=43EEbFiKkAmWcmFfQbfwb4FY/ncox3lU9JlIQVU6HFo=; b=5+UFINCuoHycJX9ZWayd0VZ6RX
	RTYHJYzQgHq5N9Ke3Tw7lX9RuJbN6KERFVfi282bReoqfACJO/MsDnzUJCDIeq1q93E2k2suxBOIt
	o2J88hYw1A9Q7XW1Rczi3RlDwaP83yyKgnrrZVrpdoAiqajie+QQ47WmU58SJiRzXerk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs/man: fix xl(1) documentation for 'pci' operations
Message-Id: <E1kq0Qw-0006Nt-Ql@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:34 +0000

commit 8bc342b043a6838c03cd86039a34e3f8eea1242f
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:25 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: fix xl(1) documentation for 'pci' operations
    
    Currently the documentation completely fails to mention the existence of
    PCI_SPEC_STRING. This patch tidies things up, specifically clarifying that
    'pci-assignable-add/remove' take <BDF> arguments where as 'pci-attach/detach'
    take <PCI_SPEC_STRING> arguments (which will be enforced in a subsequent
    patch).
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.1.pod.in | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index eaa72faad6..af31d2b572 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1597,14 +1597,18 @@ List virtual network interfaces for a domain.
 
 =item B<pci-assignable-list>
 
-List all the assignable PCI devices.
+List all the B<BDF> of assignable PCI devices. See
+L<xl-pci-configuration(5)> for more information.
+
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
 =item B<pci-assignable-add> I<BDF>
 
-Make the device at PCI Bus/Device/Function BDF assignable to guests.
+Make the device at B<BDF> assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
+
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
 first be unbound, and the original driver stored so that it can be
@@ -1620,8 +1624,10 @@ being used.
 
 =item B<pci-assignable-remove> [I<-r>] I<BDF>
 
-Make the device at PCI Bus/Device/Function BDF not assignable to
-guests.  This will at least unbind the device from pciback, and
+Make the device at B<BDF> not assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
+
+This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
 option is specified, it will also attempt to re-bind the device to its
 original driver, making it usable by Domain 0 again.  If the device is
@@ -1637,15 +1643,15 @@ As always, this should only be done if you trust the guest, or are
 confident that the particular device you're re-assigning to dom0 will
 cancel all in-flight DMA on FLR.
 
-=item B<pci-attach> I<domain-id> I<BDF>
+=item B<pci-attach> I<domain-id> I<PCI_SPEC_STRING>
 
-Hot-plug a new pass-through pci device to the specified domain.
-B<BDF> is the PCI Bus/Device/Function of the physical device to pass-through.
+Hot-plug a new pass-through pci device to the specified domain. See
+L<xl-pci-configuration(5)> for more information.
 
-=item B<pci-detach> [I<OPTIONS>] I<domain-id> I<BDF>
+=item B<pci-detach> [I<OPTIONS>] I<domain-id> I<PCI_SPEC_STRING>
 
-Hot-unplug a previously assigned pci device from a domain. B<BDF> is the PCI
-Bus/Device/Function of the physical device to be removed from the guest domain.
+Hot-unplug a pci device that was previously passed through to a domain. See
+L<xl-pci-configuration(5)> for more information.
 
 B<OPTIONS>
 
@@ -1660,7 +1666,7 @@ even without guest domain's collaboration.
 
 =item B<pci-list> I<domain-id>
 
-List pass-through pci devices for a domain.
+List the B<BDF> of pci devices passed through to a domain.
 
 =back
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56173.98128 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0R8-0005bv-6n; Thu, 17 Dec 2020 21:03:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56173.98128; Thu, 17 Dec 2020 21:03:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0R8-0005bn-35; Thu, 17 Dec 2020 21:03:46 +0000
Received: by outflank-mailman (input) for mailman id 56173;
 Thu, 17 Dec 2020 21:03:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0R6-0005bf-W0
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0R6-0007vd-VE
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0R6-0006Oh-UX
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AeaxX3MUsAK7Fc4Qjgvr2HSEVRRKK7CKkzk1EsNF/94=; b=mO5mt6ZDIUGknwjjMAfkjq+FVN
	93e/AbNwPUMlZfxSa/EWbxmYe3vXEMOnYGDKYyMykNiYTodeUxWLMAelg5RTLsWvmfv0+/0EzB+jy
	tVBRrUwpSQwFRPSGxpQcB9FewhtVkQodDULJQ+v/vKxi/sWUnXe4TcfT+ULKRnCb1ezU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: introduce 'libxl_pci_bdf' in the idl...
Message-Id: <E1kq0R6-0006Oh-UX@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:44 +0000

commit 929f23114061a0089e6d63d109cf6a1d03d35c71
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:26 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: introduce 'libxl_pci_bdf' in the idl...
    
    ... and use in 'libxl_device_pci'
    
    This patch is preparatory work for restricting the type passed to functions
    that only require BDF information, rather than passing a 'libxl_device_pci'
    structure which is only partially filled. In this patch only the minimal
    mechanical changes necessary to deal with the structural changes are made.
    Subsequent patches will adjust the code to make better use of the new type.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Acked-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
 tools/golang/xenlight/helpers.gen.go |  77 ++++++++++++------
 tools/golang/xenlight/types.gen.go   |   8 +-
 tools/include/libxl.h                |   6 ++
 tools/libs/light/libxl_dm.c          |   8 +-
 tools/libs/light/libxl_internal.h    |   3 +-
 tools/libs/light/libxl_pci.c         | 148 +++++++++++++++++------------------
 tools/libs/light/libxl_types.idl     |  16 ++--
 tools/libs/util/libxlu_pci.c         |   8 +-
 tools/xl/xl_pci.c                    |   6 +-
 tools/xl/xl_sxp.c                    |   4 +-
 10 files changed, 167 insertions(+), 117 deletions(-)

diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index c8605994e7..b7230f693c 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1999,6 +1999,41 @@ xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)}
  return nil
  }
 
+// NewPciBdf returns an instance of PciBdf initialized with defaults.
+func NewPciBdf() (*PciBdf, error) {
+var (
+x PciBdf
+xc C.libxl_pci_bdf)
+
+C.libxl_pci_bdf_init(&xc)
+defer C.libxl_pci_bdf_dispose(&xc)
+
+if err := x.fromC(&xc); err != nil {
+return nil, err }
+
+return &x, nil}
+
+func (x *PciBdf) fromC(xc *C.libxl_pci_bdf) error {
+ x.Func = byte(xc._func)
+x.Dev = byte(xc.dev)
+x.Bus = byte(xc.bus)
+x.Domain = int(xc.domain)
+
+ return nil}
+
+func (x *PciBdf) toC(xc *C.libxl_pci_bdf) (err error){defer func(){
+if err != nil{
+C.libxl_pci_bdf_dispose(xc)}
+}()
+
+xc._func = C.uint8_t(x.Func)
+xc.dev = C.uint8_t(x.Dev)
+xc.bus = C.uint8_t(x.Bus)
+xc.domain = C.int(x.Domain)
+
+ return nil
+ }
+
 // NewDevicePci returns an instance of DevicePci initialized with defaults.
 func NewDevicePci() (*DevicePci, error) {
 var (
@@ -2014,10 +2049,9 @@ return nil, err }
 return &x, nil}
 
 func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
- x.Func = byte(xc._func)
-x.Dev = byte(xc.dev)
-x.Bus = byte(xc.bus)
-x.Domain = int(xc.domain)
+ if err := x.Bdf.fromC(&xc.bdf);err != nil {
+return fmt.Errorf("converting field Bdf: %v", err)
+}
 x.Vdevfn = uint32(xc.vdevfn)
 x.VfuncMask = uint32(xc.vfunc_mask)
 x.Msitranslate = bool(xc.msitranslate)
@@ -2033,10 +2067,9 @@ if err != nil{
 C.libxl_device_pci_dispose(xc)}
 }()
 
-xc._func = C.uint8_t(x.Func)
-xc.dev = C.uint8_t(x.Dev)
-xc.bus = C.uint8_t(x.Bus)
-xc.domain = C.int(x.Domain)
+if err := x.Bdf.toC(&xc.bdf); err != nil {
+return fmt.Errorf("converting field Bdf: %v", err)
+}
 xc.vdevfn = C.uint32_t(x.Vdevfn)
 xc.vfunc_mask = C.uint32_t(x.VfuncMask)
 xc.msitranslate = C.bool(x.Msitranslate)
@@ -2766,13 +2799,13 @@ if err := x.Nics[i].fromC(&v); err != nil {
 return fmt.Errorf("converting field Nics: %v", err) }
 }
 }
-x.Pcidevs = nil
-if n := int(xc.num_pcidevs); n > 0 {
-cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n]
-x.Pcidevs = make([]DevicePci, n)
-for i, v := range cPcidevs {
-if err := x.Pcidevs[i].fromC(&v); err != nil {
-return fmt.Errorf("converting field Pcidevs: %v", err) }
+x.Pcis = nil
+if n := int(xc.num_pcis); n > 0 {
+cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:n:n]
+x.Pcis = make([]DevicePci, n)
+for i, v := range cPcis {
+if err := x.Pcis[i].fromC(&v); err != nil {
+return fmt.Errorf("converting field Pcis: %v", err) }
 }
 }
 x.Rdms = nil
@@ -2922,13 +2955,13 @@ return fmt.Errorf("converting field Nics: %v", err)
 }
 }
 }
-if numPcidevs := len(x.Pcidevs); numPcidevs > 0 {
-xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs)*C.sizeof_libxl_device_pci))
-xc.num_pcidevs = C.int(numPcidevs)
-cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
-for i,v := range x.Pcidevs {
-if err := v.toC(&cPcidevs[i]); err != nil {
-return fmt.Errorf("converting field Pcidevs: %v", err)
+if numPcis := len(x.Pcis); numPcis > 0 {
+xc.pcis = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcis)*C.sizeof_libxl_device_pci))
+xc.num_pcis = C.int(numPcis)
+cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:numPcis:numPcis]
+for i,v := range x.Pcis {
+if err := v.toC(&cPcis[i]); err != nil {
+return fmt.Errorf("converting field Pcis: %v", err)
 }
 }
 }
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index b4c5df0f2c..bc62ae8ce9 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -707,11 +707,15 @@ ColoCheckpointHost string
 ColoCheckpointPort string
 }
 
-type DevicePci struct {
+type PciBdf struct {
 Func byte
 Dev byte
 Bus byte
 Domain int
+}
+
+type DevicePci struct {
+Bdf PciBdf
 Vdevfn uint32
 VfuncMask uint32
 Msitranslate bool
@@ -896,7 +900,7 @@ CInfo DomainCreateInfo
 BInfo DomainBuildInfo
 Disks []DeviceDisk
 Nics []DeviceNic
-Pcidevs []DevicePci
+Pcis []DevicePci
 Rdms []DeviceRdm
 Dtdevs []DeviceDtdev
 Vfbs []DeviceVfb
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 3433c950f9..1fa4c5806d 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -463,6 +463,12 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
 
+/*
+ * LIBXL_HAVE_PCI_BDF indicates that the 'libxl_pci_bdf' type is defined
+ * is embedded in the 'libxl_device_pci' type.
+ */
+#define LIBXL_HAVE_PCI_BDF 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 3da83259c0..1b951b0920 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -472,10 +472,10 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     for (i = 0; i < d_config->num_pcidevs; i++) {
         unsigned int n, nr_entries;
 
-        seg = d_config->pcidevs[i].domain;
-        bus = d_config->pcidevs[i].bus;
-        devfn = PCI_DEVFN(d_config->pcidevs[i].dev,
-                          d_config->pcidevs[i].func);
+        seg = d_config->pcidevs[i].bdf.domain;
+        bus = d_config->pcidevs[i].bdf.bus;
+        devfn = PCI_DEVFN(d_config->pcidevs[i].bdf.dev,
+                          d_config->pcidevs[i].bdf.func);
         nr_entries = 0;
         rc = libxl__xc_device_get_rdm(gc, 0,
                                       seg, bus, devfn, &nr_entries, &xrdm);
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index c79523ba92..6be7b12e4c 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,10 +4746,11 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
+#define COMPARE_BDF(a, b) ((a)->domain == (b)->domain && \
                            (a)->bus == (b)->bus &&       \
                            (a)->dev == (b)->dev &&       \
                            (a)->func == (b)->func)
+#define COMPARE_PCI(a, b) COMPARE_BDF(&((a)->bdf), &((b)->bdf))
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 74c2196ae3..6b14f0f29e 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -29,10 +29,10 @@ static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pci->domain << 16;
-    value |= (pci->bus & 0xff) << 8;
-    value |= (pci->dev & 0x1f) << 3;
-    value |= (pci->func & 0x7);
+    value = pci->bdf.domain << 16;
+    value |= (pci->bdf.bus & 0xff) << 8;
+    value |= (pci->bdf.dev & 0x1f) << 3;
+    value |= (pci->bdf.func & 0x7);
 
     return value;
 }
@@ -41,10 +41,10 @@ static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pci->domain = domain;
-    pci->bus = bus;
-    pci->dev = dev;
-    pci->func = func;
+    pci->bdf.domain = domain;
+    pci->bdf.bus = bus;
+    pci->bdf.dev = dev;
+    pci->bdf.func = func;
     pci->vdevfn = vdevfn;
 }
 
@@ -54,9 +54,9 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             const libxl_device_pci *pci)
 {
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     if (pci->vdevfn)
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
@@ -250,8 +250,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pci->domain && bus == pci->bus &&
-            pci->dev == dev && pci->func == func) {
+        if (domain == pci->bdf.domain && bus == pci->bdf.bus &&
+            pci->bdf.dev == dev && pci->bdf.func == func) {
             break;
         }
     }
@@ -362,8 +362,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
-                    pci->dev, pci->func);
+    buf = GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus,
+                    pci->bdf.dev, pci->bdf.func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -383,10 +383,10 @@ static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->domain, pci->bus, pci->dev, pci->func,
+                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->domain, pci->bus, pci->dev, pci->func);
+                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 }
 
 
@@ -484,10 +484,10 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pci->domain,
-                           pci->bus,
-                           pci->dev,
-                           pci->func);
+                           pci->bdf.domain,
+                           pci->bdf.bus,
+                           pci->bdf.dev,
+                           pci->bdf.func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -517,7 +517,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pci->domain, pci->bus, pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -525,7 +525,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -533,7 +533,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
 
@@ -544,7 +544,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pci->domain, pci->bus, pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -552,7 +552,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -560,7 +560,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         return 0xffff;
     }
 
@@ -571,14 +571,14 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pci->domain, pci->bus, pci->dev, pci->func);
+                     pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -587,7 +587,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         ret = ERROR_FAIL;
     }
 
@@ -654,10 +654,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pci->domain
-            && bus == pci->bus
-            && dev == pci->dev
-            && func == pci->func) {
+        if (dom == pci->bdf.domain
+            && bus == pci->bdf.bus
+            && dev == pci->bdf.dev
+            && func == pci->bdf.func) {
             rc = 1;
             goto out;
         }
@@ -683,8 +683,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pci->domain, pci->bus,
-                      pci->dev, pci->func);
+                      pci->bdf.domain, pci->bdf.bus,
+                      pci->bdf.dev, pci->bdf.func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -747,10 +747,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pci->domain;
-    bus = pci->bus;
-    dev = pci->dev;
-    func = pci->func;
+    dom = pci->bdf.domain;
+    bus = pci->bdf.bus;
+    dev = pci->bdf.dev;
+    func = pci->bdf.func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -824,8 +824,8 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
     /* De-quarantine */
     rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
-            pci->dev, pci->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->bdf.domain, pci->bdf.bus,
+            pci->bdf.dev, pci->bdf.func);
         return ERROR_FAIL;
     }
 
@@ -914,11 +914,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigne
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pci->domain != dom )
+        if ( pci->bdf.domain != dom )
             continue;
-        if ( pci->bus != bus )
+        if ( pci->bdf.bus != bus )
             continue;
-        if ( pci->dev != dev )
+        if ( pci->bdf.dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -967,13 +967,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
     if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pci->domain, pci->bus, pci->dev,
-                         pci->func, pci->vdevfn, pci->msitranslate,
+                         pci->bdf.domain, pci->bdf.bus, pci->bdf.dev,
+                         pci->bdf.func, pci->vdevfn, pci->msitranslate,
                          pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pci->domain,  pci->bus, pci->dev,
-                         pci->func, pci->msitranslate, pci->power_mgmt);
+                         pci->bdf.domain,  pci->bdf.bus, pci->bdf.dev,
+                         pci->bdf.func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1132,10 +1132,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bus, pci->dev, pci->func);
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pci->domain,
-                           pci->bus, pci->dev, pci->func);
+                           "%04x:%02x:%02x.%01x", pci->bdf.domain,
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
                                PCI_SLOT(pci->vdevfn),
@@ -1223,7 +1223,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bus, pci->dev, pci->func);
+                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1314,8 +1314,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
-                           pci->bus, pci->dev, pci->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1355,8 +1355,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
-                                pci->bus, pci->dev, pci->func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
+                                pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1527,7 +1527,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pci->domain, pci->bus, pci->dev, pci->func,
+                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
@@ -1545,7 +1545,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
 
     if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pci->domain, pci->bus, pci->dev, pci->func);
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         rc = ERROR_FAIL;
         goto out;
     }
@@ -1553,7 +1553,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
-    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
+    libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
@@ -1634,13 +1634,13 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
         pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pci->func);
+        pfunc_mask = (1 << pci->bdf.func);
     }
 
     for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->func = i;
+                pci->bdf.func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 /* if not passing through multiple devices in a block make
@@ -1672,7 +1672,7 @@ static void device_pci_add_done(libxl__egc *egc,
         LOGD(ERROR, domid,
              "libxl__device_pci_add  failed for "
              "PCI device %x:%x:%x.%x (rc %d)",
-             pci->domain, pci->bus, pci->dev, pci->func,
+             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
              rc);
         pci_info_xs_remove(gc, pci, "domid");
     }
@@ -1741,8 +1741,8 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
-                     pci->bus, pci->dev, pci->func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->bdf.domain,
+                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
@@ -1856,8 +1856,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
-                                     pci->bus, pci->dev, pci->func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
+                                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -1892,8 +1892,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
-                               pci->bus, pci->dev, pci->func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
+                               pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1957,7 +1957,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bus, pci->dev, pci->func);
+                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2026,7 +2026,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bus, pci->dev, pci->func);
+                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2077,7 +2077,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
+         PCI_PT_QDEV_ID, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2110,7 +2110,7 @@ static void pci_remove_detached(libxl__egc *egc,
 
     /* don't do multiple resets while some functions are still passed through */
     if ((pci->vdevfn & 0x7) == 0) {
-        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
+        libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
     }
 
     if (!isstubdom) {
@@ -2198,7 +2198,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
         }
         pci->vfunc_mask &= prs->pfunc_mask;
     } else {
-        prs->pfunc_mask = (1 << pci->func);
+        prs->pfunc_mask = (1 << pci->bdf.func);
     }
 
     rc = 0;
@@ -2226,7 +2226,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->func = i;
+                pci->bdf.func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 pci->vdevfn = orig_vdev;
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 05324736b7..21a2cf5c1c 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -770,18 +770,22 @@ libxl_device_nic = Struct("device_nic", [
     ("colo_checkpoint_port", string)
     ])
 
+libxl_pci_bdf = Struct("pci_bdf", [
+    ("func", uint8),
+    ("dev", uint8),
+    ("bus", uint8),
+    ("domain", integer),
+    ])
+
 libxl_device_pci = Struct("device_pci", [
-    ("func",      uint8),
-    ("dev",       uint8),
-    ("bus",       uint8),
-    ("domain",    integer),
-    ("vdevfn",    uint32),
+    ("bdf", libxl_pci_bdf),
+    ("vdevfn", uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
     ("power_mgmt", bool),
     ("permissive", bool),
     ("seize", bool),
-    ("rdm_policy",      libxl_rdm_reserve_policy),
+    ("rdm_policy", libxl_rdm_reserve_policy),
     ])
 
 libxl_device_rdm = Struct("device_rdm", [
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 1d38fffce3..5c107f2642 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -27,10 +27,10 @@ static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                            unsigned int bus, unsigned int dev,
                            unsigned int func, unsigned int vdevfn)
 {
-    pci->domain = domain;
-    pci->bus = bus;
-    pci->dev = dev;
-    pci->func = func;
+    pci->bdf.domain = domain;
+    pci->bdf.bus = bus;
+    pci->bdf.dev = dev;
+    pci->bdf.func = func;
     pci->vdevfn = vdevfn;
     return 0;
 }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index f71498cbb5..b6dc7c2840 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -34,7 +34,8 @@ static void pcilist(uint32_t domid)
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
-               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
+               pcis[i].bdf.func);
     }
     libxl_device_pci_list_free(pcis, num);
 }
@@ -163,7 +164,8 @@ static void pciassignable_list(void)
         return;
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
-               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
+               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
+               pcis[i].bdf.func);
     }
     libxl_device_pci_assignable_list_free(pcis, num);
 }
diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c
index 359a001570..dc49fb7d50 100644
--- a/tools/xl/xl_sxp.c
+++ b/tools/xl/xl_sxp.c
@@ -194,8 +194,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh)
         fprintf(fh, "\t(device\n");
         fprintf(fh, "\t\t(pci\n");
         fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
-               d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
-               d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
+               d_config->pcidevs[i].bdf.domain, d_config->pcidevs[i].bdf.bus,
+               d_config->pcidevs[i].bdf.dev, d_config->pcidevs[i].bdf.func,
                d_config->pcidevs[i].vdevfn);
         fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n",
                d_config->pcidevs[i].msitranslate,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:03:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:03:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56174.98132 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0RJ-0005dT-A1; Thu, 17 Dec 2020 21:03:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56174.98132; Thu, 17 Dec 2020 21:03:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0RJ-0005dL-6w; Thu, 17 Dec 2020 21:03:57 +0000
Received: by outflank-mailman (input) for mailman id 56174;
 Thu, 17 Dec 2020 21:03:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RH-0005d5-2f
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RH-0007vq-1y
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RH-0006Pq-1J
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:03:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Ho6lB+r8q3CwqfjaTE0zEFtgbrN+tIO/4uI5IWUNhd0=; b=COOVxLXf8IUGNwhFGfkt39dbTx
	3xj8GJ7cqomnbWq+DEYlTrchN/ajXQc36guDIjdzFwr07M1/JHJRvdK+t4vsWjfEYtuiWdH97XrqV
	1oC2ANrRWFo/M61IAEfEy8Euw4t0tumEQ/EyHCZDnQMDVW9+Ng2eNPJSgsV35RFqxM7k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxlu: introduce xlu_pci_parse_spec_string()
Message-Id: <E1kq0RH-0006Pq-1J@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:03:55 +0000

commit 96ed6ff29741df820217b6b744eb0fa2d76b50f3
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:27 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxlu: introduce xlu_pci_parse_spec_string()
    
    This patch largely re-writes the code to parse a PCI_SPEC_STRING and enters
    it via the newly introduced function. The new parser also deals with 'bdf'
    and 'vslot' as non-positional paramaters, as per the documentation in
    xl-pci-configuration(5).
    
    The existing xlu_pci_parse_bdf() function remains, but now strictly parses
    BDF values. Some existing callers of xlu_pci_parse_bdf() are
    modified to call xlu_pci_parse_spec_string() as per the documentation in xl(1).
    
    NOTE: Usage text in xl_cmdtable.c and error messages are also modified
          appropriately.
          As a side-effect this patch also fixes a bug where using '*' to specify
          all functions would lead to an assertion failure at the end of
          xlu_pci_parse_bdf().
    
    Fixes: d25cc3ec93eb ("libxl: workaround gcc 10.2 maybe-uninitialized warning")
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxlutil.h    |   8 +-
 tools/libs/util/libxlu_pci.c | 354 +++++++++++++++++++++++--------------------
 tools/xl/xl_cmdtable.c       |   4 +-
 tools/xl/xl_parse.c          |   4 +-
 tools/xl/xl_pci.c            |  37 +++--
 5 files changed, 220 insertions(+), 187 deletions(-)

diff --git a/tools/include/libxlutil.h b/tools/include/libxlutil.h
index 92e35c5462..cdd6aab4f8 100644
--- a/tools/include/libxlutil.h
+++ b/tools/include/libxlutil.h
@@ -108,10 +108,16 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs,
    * resulting disk struct is used with libxl.
    */
 
+/*
+ * PCI BDF
+ */
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str);
+
 /*
  * PCI specification parsing
  */
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str);
+int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pci,
+                              const char *str);
 
 /*
  * RDM parsing
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 5c107f2642..a8b6ce5427 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -1,5 +1,7 @@
 #define _GNU_SOURCE
 
+#include <ctype.h>
+
 #include "libxlu_internal.h"
 #include "libxlu_disk_l.h"
 #include "libxlu_disk_i.h"
@@ -9,185 +11,213 @@
 #define XLU__PCI_ERR(_c, _x, _a...) \
     if((_c) && (_c)->report) fprintf((_c)->report, _x, ##_a)
 
-static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
+static int parse_bdf(libxl_pci_bdf *bdfp, uint32_t *vfunc_maskp,
+                     const char *str, const char **endp)
 {
-    unsigned long ret;
-    char *end;
-
-    ret = strtoul(str, &end, 16);
-    if ( end == str || *end != '\0' )
-        return -1;
-    if ( ret & ~mask )
-        return -1;
-    *val = (unsigned int)ret & mask;
+    const char *ptr = str;
+    unsigned int colons = 0;
+    unsigned int domain, bus, dev, func;
+    int n;
+
+    /* Count occurrences of ':' to detrmine presence/absence of the 'domain' */
+    while (isxdigit(*ptr) || *ptr == ':') {
+        if (*ptr == ':')
+            colons++;
+        ptr++;
+    }
+
+    ptr = str;
+    switch (colons) {
+    case 1:
+        domain = 0;
+        if (sscanf(ptr, "%x:%x.%n", &bus, &dev, &n) != 2)
+            return ERROR_INVAL;
+        break;
+    case 2:
+        if (sscanf(ptr, "%x:%x:%x.%n", &domain, &bus, &dev, &n) != 3)
+            return ERROR_INVAL;
+        break;
+    default:
+        return ERROR_INVAL;
+    }
+
+    if (domain > 0xffff || bus > 0xff || dev > 0x1f)
+        return ERROR_INVAL;
+
+    ptr += n;
+    if (*ptr == '*') {
+        if (!vfunc_maskp)
+            return ERROR_INVAL;
+        *vfunc_maskp = LIBXL_PCI_FUNC_ALL;
+        func = 0;
+        ptr++;
+    } else {
+        if (sscanf(ptr, "%x%n", &func, &n) != 1)
+            return ERROR_INVAL;
+        if (func > 7)
+            return ERROR_INVAL;
+        if (vfunc_maskp)
+            *vfunc_maskp = 1;
+        ptr += n;
+    }
+
+    bdfp->domain = domain;
+    bdfp->bus = bus;
+    bdfp->dev = dev;
+    bdfp->func = func;
+
+    if (endp)
+        *endp = ptr;
+
     return 0;
 }
 
-static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
-                           unsigned int bus, unsigned int dev,
-                           unsigned int func, unsigned int vdevfn)
+static int parse_vslot(uint32_t *vdevfnp, const char *str, const char **endp)
 {
-    pci->bdf.domain = domain;
-    pci->bdf.bus = bus;
-    pci->bdf.dev = dev;
-    pci->bdf.func = func;
-    pci->vdevfn = vdevfn;
+    const char *ptr = str;
+    unsigned int val;
+    int n;
+
+    if (sscanf(ptr, "%x%n", &val, &n) != 1)
+        return ERROR_INVAL;
+
+    if (val > 0x1f)
+        return ERROR_INVAL;
+
+    ptr += n;
+
+    *vdevfnp = val << 3;
+
+    if (endp)
+        *endp = ptr;
+
     return 0;
 }
 
-#define STATE_DOMAIN    0
-#define STATE_BUS       1
-#define STATE_DEV       2
-#define STATE_FUNC      3
-#define STATE_VSLOT     4
-#define STATE_OPTIONS_K 6
-#define STATE_OPTIONS_V 7
-#define STATE_TERMINAL  8
-#define STATE_TYPE      9
-#define STATE_RDM_STRATEGY      10
-#define STATE_RESERVE_POLICY    11
-#define INVALID         0xffffffff
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
+static int parse_key_val(char **keyp, char**valp, const char *str,
+                         const char **endp)
 {
-    unsigned state = STATE_DOMAIN;
-    unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
-    char *buf2, *tok, *ptr, *end, *optkey = NULL;
+    const char *ptr = str;
+    char *key, *val;
+
+    while (*ptr != '=' && *ptr != '\0')
+        ptr++;
 
-    if ( NULL == (buf2 = ptr = strdup(str)) )
+    if (*ptr == '\0')
+        return ERROR_INVAL;
+
+    key = strndup(str, ptr - str);
+    if (!key)
         return ERROR_NOMEM;
 
-    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
-        switch(state) {
-        case STATE_DOMAIN:
-            if ( *ptr == ':' ) {
-                state = STATE_BUS;
-                *ptr = '\0';
-                if ( hex_convert(tok, &dom, 0xffff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_BUS:
-            if ( *ptr == ':' ) {
-                state = STATE_DEV;
-                *ptr = '\0';
-                if ( hex_convert(tok, &bus, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }else if ( *ptr == '.' ) {
-                state = STATE_FUNC;
-                *ptr = '\0';
-                if ( dom & ~0xff )
-                    goto parse_error;
-                bus = dom;
-                dom = 0;
-                if ( hex_convert(tok, &dev, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_DEV:
-            if ( *ptr == '.' ) {
-                state = STATE_FUNC;
-                *ptr = '\0';
-                if ( hex_convert(tok, &dev, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_FUNC:
-            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
-                switch( *ptr ) {
-                case '\0':
-                    state = STATE_TERMINAL;
-                    break;
-                case '@':
-                    state = STATE_VSLOT;
-                    break;
-                case ',':
-                    state = STATE_OPTIONS_K;
-                    break;
-                }
-                *ptr = '\0';
-                if ( !strcmp(tok, "*") ) {
-                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
-                }else{
-                    if ( hex_convert(tok, &func, 0x7) )
-                        goto parse_error;
-                    pci->vfunc_mask = (1 << 0);
-                }
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_VSLOT:
-            if ( *ptr == '\0' || *ptr == ',' ) {
-                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
-                *ptr = '\0';
-                if ( hex_convert(tok, &vslot, 0xff) )
-                    goto parse_error;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_OPTIONS_K:
-            if ( *ptr == '=' ) {
-                state = STATE_OPTIONS_V;
-                *ptr = '\0';
-                optkey = tok;
-                tok = ptr + 1;
-            }
-            break;
-        case STATE_OPTIONS_V:
-            if ( *ptr == ',' || *ptr == '\0' ) {
-                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
-                *ptr = '\0';
-                if ( !strcmp(optkey, "msitranslate") ) {
-                    pci->msitranslate = atoi(tok);
-                }else if ( !strcmp(optkey, "power_mgmt") ) {
-                    pci->power_mgmt = atoi(tok);
-                }else if ( !strcmp(optkey, "permissive") ) {
-                    pci->permissive = atoi(tok);
-                }else if ( !strcmp(optkey, "seize") ) {
-                    pci->seize = atoi(tok);
-                } else if (!strcmp(optkey, "rdm_policy")) {
-                    if (!strcmp(tok, "strict")) {
-                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
-                    } else if (!strcmp(tok, "relaxed")) {
-                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
-                    } else {
-                        XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
-                                          " policy: 'strict' or 'relaxed'.",
-                                     tok);
-                        goto parse_error;
-                    }
-                } else {
-                    XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey);
-                }
-                tok = ptr + 1;
-            }
-        default:
-            break;
+    str = ++ptr; /* skip '=' */
+    while (*ptr != ',' && *ptr != '\0')
+        ptr++;
+
+    val = strndup(str, ptr - str);
+    if (!val) {
+        free(key);
+        return ERROR_NOMEM;
+    }
+
+    if (*ptr == ',')
+        ptr++;
+
+    *keyp = key;
+    *valp = val;
+    *endp = ptr;
+
+    return 0;
+}
+
+static int parse_rdm_policy(XLU_Config *cfg, libxl_rdm_reserve_policy *policy,
+                            const char *str)
+{
+    int ret = libxl_rdm_reserve_policy_from_string(str, policy);
+
+    if (ret)
+        XLU__PCI_ERR(cfg, "Unknown RDM policy: %s", str);
+
+    return ret;
+}
+
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str)
+{
+    return parse_bdf(bdf, NULL, str, NULL);
+}
+
+int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
+                              const char *str)
+{
+    const char *ptr = str;
+    bool bdf_present = false;
+    int ret;
+
+    /* Attempt to parse 'bdf' as positional parameter */
+    ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, ptr, &ptr);
+    if (!ret) {
+        bdf_present = true;
+
+        /* Check whether 'vslot' if present */
+        if (*ptr == '@') {
+            ret = parse_vslot(&pcidev->vdevfn, ++ptr, &ptr);
+            if (ret)
+                return ret;
         }
+        if (*ptr == ',')
+            ptr++;
+        else if (*ptr != '\0')
+            return ERROR_INVAL;
     }
 
-    if ( tok != ptr || state != STATE_TERMINAL )
-        goto parse_error;
+    /* Parse the rest as 'key=val' pairs */
+    while (*ptr != '\0') {
+        char *key, *val;
 
-    assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
+        ret = parse_key_val(&key, &val, ptr, &ptr);
+        if (ret)
+            return ret;
 
-    /* Just a pretty way to fill in the values */
-    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
+        if (!strcmp(key, "bdf")) {
+            ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, val, NULL);
+            bdf_present = !ret;
+        } else if (!strcmp(key, "vslot")) {
+            ret = parse_vslot(&pcidev->vdevfn, val, NULL);
+        } else if (!strcmp(key, "permissive")) {
+            pcidev->permissive = atoi(val);
+        } else if (!strcmp(key, "msitranslate")) {
+            pcidev->msitranslate = atoi(val);
+        } else if (!strcmp(key, "seize")) {
+            pcidev->seize= atoi(val);
+        } else if (!strcmp(key, "power_mgmt")) {
+            pcidev->power_mgmt = atoi(val);
+        } else if (!strcmp(key, "rdm_policy")) {
+            ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
+        } else {
+            XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
+            ret = ERROR_INVAL;
+        }
 
-    free(buf2);
+        free(key);
+        free(val);
 
-    return 0;
+        if (ret)
+            return ret;
+    }
 
-parse_error:
-    free(buf2);
-    return ERROR_INVAL;
+    if (!bdf_present)
+        return ERROR_INVAL;
+
+    return 0;
 }
 
 int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 {
+#define STATE_TYPE           0
+#define STATE_RDM_STRATEGY   1
+#define STATE_RESERVE_POLICY 2
+#define STATE_TERMINAL       3
+
     unsigned state = STATE_TYPE;
     char *buf2, *tok, *ptr, *end;
 
@@ -227,15 +257,8 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
             if (*ptr == ',' || *ptr == '\0') {
                 state = *ptr == ',' ? STATE_TYPE : STATE_TERMINAL;
                 *ptr = '\0';
-                if (!strcmp(tok, "strict")) {
-                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
-                } else if (!strcmp(tok, "relaxed")) {
-                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
-                } else {
-                    XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s",
-                                 tok);
+                if (!parse_rdm_policy(cfg, &rdm->policy, tok))
                     goto parse_error;
-                }
                 tok = ptr + 1;
             }
         default:
@@ -253,6 +276,11 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 parse_error:
     free(buf2);
     return ERROR_INVAL;
+
+#undef STATE_TYPE
+#undef STATE_RDM_STRATEGY
+#undef STATE_RESERVE_POLICY
+#undef STATE_TERMINAL
 }
 
 /*
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 6ab5e47da3..30e17a2848 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -90,12 +90,12 @@ struct cmd_spec cmd_table[] = {
     { "pci-attach",
       &main_pciattach, 0, 1,
       "Insert a new pass-through pci device",
-      "<Domain> <BDF> [Virtual Slot]",
+      "<Domain> <PCI_SPEC_STRING>",
     },
     { "pci-detach",
       &main_pcidetach, 0, 1,
       "Remove a domain's pass-through pci device",
-      "<Domain> <BDF>",
+      "<Domain> <PCI_SPEC_STRING>",
     },
     { "pci-list",
       &main_pcilist, 0, 0,
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 4ebf39620a..867e4d068a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1487,10 +1487,10 @@ void parse_config_data(const char *config_source,
              * the global policy by default.
              */
             pci->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_bdf(config, pci, buf);
+            e = xlu_pci_parse_spec_string(config, pci, buf);
             if (e) {
                 fprintf(stderr,
-                        "unable to parse PCI BDF `%s' for passthrough\n",
+                        "unable to parse PCI_SPEC_STRING `%s' for passthrough\n",
                         buf);
                 exit(-e);
             }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index b6dc7c2840..9c24496cb2 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -55,7 +55,7 @@ int main_pcilist(int argc, char **argv)
     return 0;
 }
 
-static int pcidetach(uint32_t domid, const char *bdf, int force)
+static int pcidetach(uint32_t domid, const char *spec_string, int force)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -66,8 +66,9 @@ static int pcidetach(uint32_t domid, const char *bdf, int force)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
+        fprintf(stderr, "pci-detach: malformed PCI_SPEC_STRING \"%s\"\n",
+                spec_string);
         exit(2);
     }
     if (force) {
@@ -89,7 +90,7 @@ int main_pcidetach(int argc, char **argv)
     uint32_t domid;
     int opt;
     int force = 0;
-    const char *bdf = NULL;
+    const char *spec_string = NULL;
 
     SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
     case 'f':
@@ -98,15 +99,15 @@ int main_pcidetach(int argc, char **argv)
     }
 
     domid = find_domain(argv[optind]);
-    bdf = argv[optind + 1];
+    spec_string = argv[optind + 1];
 
-    if (pcidetach(domid, bdf, force))
+    if (pcidetach(domid, spec_string, force))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciattach(uint32_t domid, const char *bdf, const char *vs)
+static int pciattach(uint32_t domid, const char *spec_string)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -117,8 +118,9 @@ static int pciattach(uint32_t domid, const char *bdf, const char *vs)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
+        fprintf(stderr, "pci-attach: malformed PCI_SPEC_STRING \"%s\"\n",
+                spec_string);
         exit(2);
     }
 
@@ -135,19 +137,16 @@ int main_pciattach(int argc, char **argv)
 {
     uint32_t domid;
     int opt;
-    const char *bdf = NULL, *vs = NULL;
+    const char *spec_string = NULL;
 
     SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
         /* No options */
     }
 
     domid = find_domain(argv[optind]);
-    bdf = argv[optind + 1];
-
-    if (optind + 1 < argc)
-        vs = argv[optind + 2];
+    spec_string = argv[optind + 1];
 
-    if (pciattach(domid, bdf, vs))
+    if (pciattach(domid, spec_string))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
@@ -193,8 +192,8 @@ static int pciassignable_add(const char *bdf, int rebind)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+        fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
@@ -235,8 +234,8 @@ static int pciassignable_remove(const char *bdf, int rebind)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
-        fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+        fprintf(stderr, "pci-assignable-remove: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56175.98136 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0RS-0005fA-CJ; Thu, 17 Dec 2020 21:04:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56175.98136; Thu, 17 Dec 2020 21:04:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0RS-0005f0-8m; Thu, 17 Dec 2020 21:04:06 +0000
Received: by outflank-mailman (input) for mailman id 56175;
 Thu, 17 Dec 2020 21:04:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RR-0005es-6M
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RR-0007wP-5X
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0RR-0006Qr-4H
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bjBnApA7BS+VhttJVpYzuwPZffTw01qJDzorsgZ+NFo=; b=XtoV3F4tnfEdLO4XJFTOryzNzt
	0zkbEQi4hfNpd2iiudc76AC+B05bIXpmPStX1QbYKgBsmnBi5tMPzSB3NyC4JPHOUZ/QVwTC4BgTE
	s2k32ACoaSDhFMJaWvto9h8zmTYdGW4CuvncVv4IxwtEuwhNYu0qYgoDAB8qGzacPg6Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs/man: modify xl(1) in preparation for naming of assignable devices
Message-Id: <E1kq0RR-0006Qr-4H@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:05 +0000

commit f73c5dd56d78008e4b9c1fd7bf26b66e0afb8b54
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:28 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    docs/man: modify xl(1) in preparation for naming of assignable devices
    
    A subsequent patch will introduce code to allow a name to be specified to
    'xl pci-assignable-add' such that the assignable device may be referred to
    by than name in subsequent operations.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl.1.pod.in | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index af31d2b572..f4779d8fd6 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1595,19 +1595,23 @@ List virtual network interfaces for a domain.
 
 =over 4
 
-=item B<pci-assignable-list>
+=item B<pci-assignable-list> [I<-n>]
 
 List all the B<BDF> of assignable PCI devices. See
-L<xl-pci-configuration(5)> for more information.
+L<xl-pci-configuration(5)> for more information. If the -n option is
+specified then any name supplied when the device was made assignable
+will also be displayed.
 
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
-=item B<pci-assignable-add> I<BDF>
+=item B<pci-assignable-add> [I<-n NAME>] I<BDF>
 
 Make the device at B<BDF> assignable to guests. See
-L<xl-pci-configuration(5)> for more information.
+L<xl-pci-configuration(5)> for more information. If the -n option is
+supplied then the assignable device entry will the named with the
+given B<NAME>.
 
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
@@ -1622,10 +1626,11 @@ not to do this on a device critical to domain 0's operation, such as
 storage controllers, network interfaces, or GPUs that are currently
 being used.
 
-=item B<pci-assignable-remove> [I<-r>] I<BDF>
+=item B<pci-assignable-remove> [I<-r>] I<BDF>|I<NAME>
 
-Make the device at B<BDF> not assignable to guests. See
-L<xl-pci-configuration(5)> for more information.
+Make a device non-assignable to guests. The device may be identified
+either by its B<BDF> or the B<NAME> supplied when the device was made
+assignable. See L<xl-pci-configuration(5)> for more information.
 
 This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56176.98139 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rc-0005gp-DT; Thu, 17 Dec 2020 21:04:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56176.98139; Thu, 17 Dec 2020 21:04:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rc-0005gh-AR; Thu, 17 Dec 2020 21:04:16 +0000
Received: by outflank-mailman (input) for mailman id 56176;
 Thu, 17 Dec 2020 21:04:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rb-0005gY-A8
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rb-0007wZ-8U
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rb-0006Rz-7o
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=P0Vp3/47S801fKDyXtgTDQ+q2IUklooaWkpoe7ZblNA=; b=Y3NUphDW9lfEnpfrh7D/SzihYx
	drxnmn6918Qtb1Xio8c4Hmee7MKO/ErXvPcwuBttR+G+hl7nNVMc9VaZehBk4FbeNpeDfdBSNR+vs
	PXbvSZDzl7hXnS5TSH+PBVSrQ9ZyEwFOAjrkX72oq+h79qPD7cRXNI1FcStagXOJOJeQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: convert internal functions in libxl_pci.c...
Message-Id: <E1kq0Rb-0006Rz-7o@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:15 +0000

commit 66c2fbc6e82b1aa7b9f0fb37eecf93983c348058
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:29 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:23 2020 +0000

    libxl: convert internal functions in libxl_pci.c...
    
    ... to use 'libx_pci_bdf' where appropriate.
    
    No API change.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/libs/light/libxl_pci.c | 192 +++++++++++++++++++++++--------------------
 1 file changed, 103 insertions(+), 89 deletions(-)

diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 6b14f0f29e..448fe96951 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,26 +25,33 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pci_encode_bdf(libxl_device_pci *pci)
+static unsigned int pci_encode_bdf(libxl_pci_bdf *pcibdf)
 {
     unsigned int value;
 
-    value = pci->bdf.domain << 16;
-    value |= (pci->bdf.bus & 0xff) << 8;
-    value |= (pci->bdf.dev & 0x1f) << 3;
-    value |= (pci->bdf.func & 0x7);
+    value = pcibdf->domain << 16;
+    value |= (pcibdf->bus & 0xff) << 8;
+    value |= (pcibdf->dev & 0x1f) << 3;
+    value |= (pcibdf->func & 0x7);
 
     return value;
 }
 
+static void pcibdf_struct_fill(libxl_pci_bdf *pcibdf, unsigned int domain,
+                               unsigned int bus, unsigned int dev,
+                               unsigned int func)
+{
+    pcibdf->domain = domain;
+    pcibdf->bus = bus;
+    pcibdf->dev = dev;
+    pcibdf->func = func;
+}
+
 static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pci->bdf.domain = domain;
-    pci->bdf.bus = bus;
-    pci->bdf.dev = dev;
-    pci->bdf.func = func;
+    pcibdf_struct_fill(&pci->bdf, domain, bus, dev, func);
     pci->vdevfn = vdevfn;
 }
 
@@ -350,8 +357,8 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num,
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
-static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
-                           libxl_device_pci *pci)
+static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
+                           libxl_pci_bdf *pcibdf)
 {
     int rc, fd;
     char *buf;
@@ -362,8 +369,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus,
-                    pci->bdf.dev, pci->bdf.func);
+    buf = GCSPRINTF(PCI_BDF, pcibdf->domain, pcibdf->bus,
+                    pcibdf->dev, pcibdf->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -378,22 +385,22 @@ static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
 
 #define PCI_INFO_PATH "/libxl/pci"
 
-static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
+static char *pci_info_xs_path(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node)
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
 }
 
 
-static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
+static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node, const char *val)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
     int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
 
     if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
@@ -401,18 +408,18 @@ static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
     return rc;
 }
 
-static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
+static char *pci_info_xs_read(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                               const char *node)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
 
     return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
+static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                                const char *node)
 {
-    char *path = pci_info_xs_path(gc, pci, node);
+    char *path = pci_info_xs_path(gc, pcibdf, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
@@ -451,9 +458,9 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         new = pcis + *num;
 
         libxl_device_pci_init(new);
-        pci_struct_fill(new, dom, bus, dev, func, 0);
+        pcibdf_struct_fill(&new->bdf, dom, bus, dev, func);
 
-        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
+        if (pci_info_xs_read(gc, &new->bdf, "domid")) /* already assigned */
             continue;
 
         (*num)++;
@@ -477,17 +484,17 @@ void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pci->bdf.domain,
-                           pci->bdf.bus,
-                           pci->bdf.dev,
-                           pci->bdf.func);
+                           pcibdf->domain,
+                           pcibdf->bus,
+                           pcibdf->dev,
+                           pcibdf->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -501,7 +508,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -639,8 +646,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for pci's BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
+/* Scan through /sys/.../pciback/slots looking for BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     FILE *f;
     int rc = 0;
@@ -654,10 +661,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pci->bdf.domain
-            && bus == pci->bdf.bus
-            && dev == pci->bdf.dev
-            && func == pci->bdf.func) {
+        if (dom == pcibdf->domain
+            && bus == pcibdf->bus
+            && dev == pcibdf->dev
+            && func == pcibdf->func) {
             rc = 1;
             goto out;
         }
@@ -667,7 +674,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     char * spath;
     int rc;
@@ -683,8 +690,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pci->bdf.domain, pci->bdf.bus,
-                      pci->bdf.dev, pci->bdf.func);
+                      pcibdf->domain, pcibdf->bus,
+                      pcibdf->dev, pcibdf->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -695,40 +702,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_assign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     int rc;
 
-    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pcibdf)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pci) < 0 ) {
+                             pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcibdf) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pcibdf, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pcibdf) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pci) < 0 ) {
+                             pcibdf) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -736,9 +743,9 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
     return 0;
 }
 
-static int libxl__device_pci_assignable_add(libxl__gc *gc,
-                                            libxl_device_pci *pci,
-                                            int rebind)
+static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
+                                         libxl_pci_bdf *pcibdf,
+                                         int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     unsigned dom, bus, dev, func;
@@ -747,10 +754,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     struct stat st;
 
     /* Local copy for convenience */
-    dom = pci->bdf.domain;
-    bus = pci->bdf.bus;
-    dev = pci->bdf.dev;
-    func = pci->bdf.func;
+    dom = pcibdf->domain;
+    bus = pcibdf->bus;
+    dev = pcibdf->dev;
+    func = pcibdf->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -760,7 +767,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pci);
+    rc = pciback_dev_is_assigned(gc, pcibdf);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
@@ -770,7 +777,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pcibdf, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -779,9 +786,9 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_info_xs_write(gc, pci, "driver_path", driver_path);
+            pci_info_xs_write(gc, pcibdf, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
+                     pci_info_xs_read(gc, pcibdf, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -789,10 +796,10 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_info_xs_remove(gc, pci, "driver_path");
+        pci_info_xs_remove(gc, pcibdf, "driver_path");
     }
 
-    if ( pciback_dev_assign(gc, pci) ) {
+    if ( pciback_dev_assign(gc, pcibdf) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
@@ -803,7 +810,7 @@ quarantine:
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -813,33 +820,33 @@ quarantine:
     return 0;
 }
 
-static int libxl__device_pci_assignable_remove(libxl__gc *gc,
-                                               libxl_device_pci *pci,
-                                               int rebind)
+static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
+                                            libxl_pci_bdf *pcibdf,
+                                            int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc;
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->bdf.domain, pci->bdf.bus,
-            pci->bdf.dev, pci->bdf.func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcibdf->domain,
+            pcibdf->bus, pcibdf->dev, pcibdf->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pcibdf)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pci);
+        pciback_dev_unassign(gc, pcibdf);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_info_xs_read(gc, pci, "driver_path");
+    driver_path = pci_info_xs_read(gc, pcibdf, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -847,12 +854,12 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pci) < 0 ) {
+                                 pcibdf) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_info_xs_remove(gc, pci, "driver_path");
+            pci_info_xs_remove(gc, pcibdf, "driver_path");
         }
     } else {
         if ( rebind ) {
@@ -870,7 +877,7 @@ int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
+    rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, rebind);
 
     GC_FREE;
     return rc;
@@ -883,7 +890,7 @@ int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
+    rc = libxl__pci_bdf_assignable_remove(gc, &pci->bdf, rebind);
 
     GC_FREE;
     return rc;
@@ -1385,7 +1392,7 @@ static void pci_add_dm_done(libxl__egc *egc,
     /* Don't restrict writes to the PCI config space from this VM */
     if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             pci) < 0 ) {
+                             &pci->bdf) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1401,7 +1408,8 @@ out_no_irq:
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(&pci->bdf),
+                             flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1480,17 +1488,21 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
+static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
 {
     libxl_device_pci *pcis;
-    int num;
-    bool assignable;
+    int num, i;
 
     pcis = libxl_device_pci_assignable_list(ctx, &num);
-    assignable = is_pci_in_array(pcis, num, pci);
+
+    for (i = 0; i < num; i++) {
+        if (COMPARE_BDF(pcibdf, &pcis[i].bdf))
+            break;
+    }
+
     libxl_device_pci_assignable_list_free(pcis, num);
 
-    return assignable;
+    return i < num;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1523,7 +1535,8 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->callback = device_pci_add_stubdom_done;
 
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
+        rc = xc_test_assign_device(ctx->xch, domid,
+                                   pci_encode_bdf(&pci->bdf));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
@@ -1537,20 +1550,20 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
-        rc = libxl__device_pci_assignable_add(gc, pci, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
+        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, 1);
         if ( rc )
             goto out;
     }
 
-    if (!libxl_pci_assignable(ctx, pci)) {
+    if (!is_bdf_assignable(ctx, &pci->bdf)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
              pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
         rc = ERROR_FAIL;
         goto out;
     }
 
-    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
+    rc = pci_info_xs_write(gc, &pci->bdf, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
     libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
@@ -1674,7 +1687,7 @@ static void device_pci_add_done(libxl__egc *egc,
              "PCI device %x:%x:%x.%x (rc %d)",
              pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
              rc);
-        pci_info_xs_remove(gc, pci, "domid");
+        pci_info_xs_remove(gc, &pci->bdf, "domid");
     }
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -2114,7 +2127,8 @@ static void pci_remove_detached(libxl__egc *egc,
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
+        rc = xc_deassign_device(CTX->xch, domid,
+                                pci_encode_bdf(&pci->bdf));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
@@ -2243,7 +2257,7 @@ out:
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
 
-    if (!rc) pci_info_xs_remove(gc, pci, "domid");
+    if (!rc) pci_info_xs_remove(gc, &pci->bdf, "domid");
 
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56177.98144 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rm-0005iQ-Gn; Thu, 17 Dec 2020 21:04:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56177.98144; Thu, 17 Dec 2020 21:04:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rm-0005iI-Dq; Thu, 17 Dec 2020 21:04:26 +0000
Received: by outflank-mailman (input) for mailman id 56177;
 Thu, 17 Dec 2020 21:04:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rl-0005i9-CQ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rl-0007wj-Bh
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rl-0006TZ-B1
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Z9EE1Pnv7S6wNolL6ckXihBjYanS7u9D7GIC6Cgghbw=; b=1ylHY6QivfRvplr/kKsp8aaRxC
	3QbR9qkcsWQ0SntzVN0C1NoB5rIC6PRf6XvZiL5qAPw63cHu3OSojgvFcArF6tYESw0ifPzMcU6zD
	hPmOfkjvTHca5ChijaevnEXXZoohhfAU+54GezRl4zIe2WaBzlPPxRzeHElLz1t7ikN8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ...
Message-Id: <E1kq0Rl-0006TZ-B1@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:25 +0000

commit 5ab684cb3e4d078f246e6fa2d8bc445959b6820e
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:30 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:26 2020 +0000

    libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ...
    
    which support naming and use 'libxl_pci_bdf' rather than 'libxl_device_pci',
    as replacements for libxl_device_pci_assignable_add/remove/list/list_free().
    
    libxl_pci_bdf_assignable_add() takes a 'name' parameter which is stored in
    xenstore and facilitates two addtional functions added by this patch:
    libxl_pci_bdf_assignable_name2bdf() and libxl_pci_bdf_assignable_bdf2name().
    Currently there are no callers of these two functions. They will be added in
    a subsequent patch.
    
    libxl_device_pci_assignable_add/remove/list/list_free() are left in place
    for compatibility but are re-implemented in terms of the newly introduced
    functions.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h        |  36 ++++++++--
 tools/libs/light/libxl_pci.c | 166 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 171 insertions(+), 31 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 1fa4c5806d..fda611f889 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -469,6 +469,13 @@
  */
 #define LIBXL_HAVE_PCI_BDF 1
 
+/*
+ * LIBXL_HAVE_PCI_ASSIGNABLE_BDF indicates that the
+ * libxl_pci_bdf_assignable_add/remove/list/list_free() functions all
+ * exist.
+ */
+#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
+
 /*
  * libxl ABI compatibility
  *
@@ -2357,9 +2364,9 @@ int libxl_device_events_handler(libxl_ctx *ctx,
                                 LIBXL_EXTERNAL_CALLERS_ONLY;
 
 /*
- * Functions related to making devices assignable -- that is, bound to
- * the pciback driver, ready to be given to a guest via
- * libxl_pci_device_add.
+ * Functions related to making PCI devices with the specified BDF
+ * assignable -- that is, bound to the pciback driver, ready to be given to
+ * a guest via libxl_pci_device_add.
  *
  * - ..._add() will unbind the device from its current driver (if
  * already bound) and re-bind it to pciback; at that point it will be
@@ -2371,16 +2378,31 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * rebind is non-zero, attempt to assign it back to the driver
  * from whence it came.
  *
- * - ..._list() will return a list of the PCI devices available to be
+ * - ..._list() will return a list of the PCI BDFs available to be
  * assigned.
  *
  * add and remove are idempotent: if the device in question is already
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
+int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                 const char *name, int rebind);
+int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                    int rebind);
+libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num);
+void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num);
+libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
+                                                 const char *name);
+char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
+                                        libxl_pci_bdf *pcibdf);
+
+/* Compatibility functions - Use libxl_pci_bdf_assignable_* instead */
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind);
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
+                                                   int *num);
 void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 448fe96951..e11574e73f 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -426,10 +426,10 @@ static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
     xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
+libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_device_pci *pcis = NULL, *new;
+    libxl_pci_bdf *pcibdfs = NULL, *new;
     struct dirent *de;
     DIR *dir;
 
@@ -450,17 +450,17 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcibdfs, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcis = new;
-        new = pcis + *num;
+        pcibdfs = new;
+        new = pcibdfs + *num;
 
-        libxl_device_pci_init(new);
-        pcibdf_struct_fill(&new->bdf, dom, bus, dev, func);
+        libxl_pci_bdf_init(new);
+        pcibdf_struct_fill(new, dom, bus, dev, func);
 
-        if (pci_info_xs_read(gc, &new->bdf, "domid")) /* already assigned */
+        if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
             continue;
 
         (*num)++;
@@ -469,15 +469,15 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
     closedir(dir);
 out:
     GC_FREE;
-    return pcis;
+    return pcibdfs;
 }
 
-void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num)
 {
     int i;
 
     for (i = 0; i < num; i++)
-        libxl_device_pci_dispose(&list[i]);
+        libxl_pci_bdf_dispose(&list[i]);
 
     free(list);
 }
@@ -745,6 +745,7 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
 
 static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
                                          libxl_pci_bdf *pcibdf,
+                                         const char *name,
                                          int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -753,6 +754,23 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     int rc;
     struct stat st;
 
+    /* Sanitise any name that was passed */
+    if (name) {
+        unsigned int i, n = strlen(name);
+
+        if (n > 64) { /* Reasonable upper bound on name length */
+            LOG(ERROR, "Name too long");
+            return ERROR_FAIL;
+        }
+
+        for (i = 0; i < n; i++) {
+            if (!isgraph(name[i])) {
+                LOG(ERROR, "Names may only include printable characters");
+                return ERROR_FAIL;
+            }
+        }
+    }
+
     /* Local copy for convenience */
     dom = pcibdf->domain;
     bus = pcibdf->bus;
@@ -773,7 +791,7 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     }
     if ( rc ) {
         LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func);
-        goto quarantine;
+        goto name;
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
@@ -804,7 +822,12 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
         return ERROR_FAIL;
     }
 
-quarantine:
+name:
+    if (name)
+        pci_info_xs_write(gc, pcibdf, "name", name);
+    else
+        pci_info_xs_remove(gc, pcibdf, "name");
+
     /*
      * DOMID_IO is just a sentinel domain, without any actual mappings,
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
@@ -868,34 +891,87 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
         }
     }
 
+    pci_info_xs_remove(gc, pcibdf, "name");
+
     return 0;
 }
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind)
+int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                 const char *name, int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, rebind);
+    rc = libxl__pci_bdf_assignable_add(gc, pcibdf, name, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind)
+int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
+                                    int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_remove(gc, &pci->bdf, rebind);
+    rc = libxl__pci_bdf_assignable_remove(gc, pcibdf, rebind);
 
     GC_FREE;
     return rc;
 }
 
+libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
+                                                 const char *name)
+{
+    GC_INIT(ctx);
+    char **bdfs;
+    libxl_pci_bdf *pcibdf = NULL;
+    unsigned int i, n;
+
+    bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n);
+    if (!n)
+        goto out;
+
+    pcibdf = calloc(1, sizeof(*pcibdf));
+    if (!pcibdf)
+        goto out;
+
+    for (i = 0; i < n; i++) {
+        unsigned dom, bus, dev, func;
+        const char *tmp;
+
+        if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4)
+            continue;
+
+        pcibdf_struct_fill(pcibdf, dom, bus, dev, func);
+
+        tmp = pci_info_xs_read(gc, pcibdf, "name");
+        if (tmp && !strcmp(tmp, name))
+            goto out;
+    }
+
+    free(pcibdf);
+    pcibdf = NULL;
+
+out:
+    GC_FREE;
+    return pcibdf;
+}
+
+char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
+                                        libxl_pci_bdf *pcibdf)
+{
+    GC_INIT(ctx);
+    char *name = NULL, *tmp = pci_info_xs_read(gc, pcibdf, "name");
+
+    if (tmp)
+        name = strdup(tmp);
+
+    GC_FREE;
+    return name;
+}
+
 /*
  * This function checks that all functions of a device are bound to pciback
  * driver. It also initialises a bit-mask of which function numbers are present
@@ -1490,17 +1566,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
 
 static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
 {
-    libxl_device_pci *pcis;
+    libxl_pci_bdf *pcibdfs;
     int num, i;
 
-    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
 
     for (i = 0; i < num; i++) {
-        if (COMPARE_BDF(pcibdf, &pcis[i].bdf))
+        if (COMPARE_BDF(pcibdf, &pcibdfs[i]))
             break;
     }
 
-    libxl_device_pci_assignable_list_free(pcis, num);
+    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
 
     return i < num;
 }
@@ -1551,7 +1627,7 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     if (rc) goto out;
 
     if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
-        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, 1);
+        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, NULL, 1);
         if ( rc )
             goto out;
     }
@@ -2449,6 +2525,48 @@ DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind)
+{
+    return libxl_pci_bdf_assignable_add(ctx, &pci->bdf, NULL, rebind);
+}
+
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind)
+{
+    return libxl_pci_bdf_assignable_remove(ctx, &pci->bdf, rebind);
+}
+
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
+                                                   int *num)
+{
+    libxl_pci_bdf *pcibdfs = libxl_pci_bdf_assignable_list(ctx, num);
+    libxl_device_pci *pcis;
+    unsigned int i;
+
+    if (!pcibdfs)
+        return NULL;
+
+    pcis = calloc(*num, sizeof(*pcis));
+    if (!pcis) {
+        libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
+        return NULL;
+    }
+
+    for (i = 0; i < *num; i++) {
+        libxl_device_pci_init(&pcis[i]);
+        libxl_pci_bdf_copy(ctx, &pcis[i].bdf, &pcibdfs[i]);
+    }
+
+    libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
+    return pcis;
+}
+
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
+{
+    libxl_device_pci_list_free(list, num);
+}
+
 /*
  * Local variables:
  * mode: C
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56178.98148 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rw-0005jn-IT; Thu, 17 Dec 2020 21:04:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56178.98148; Thu, 17 Dec 2020 21:04:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Rw-0005jf-FQ; Thu, 17 Dec 2020 21:04:36 +0000
Received: by outflank-mailman (input) for mailman id 56178;
 Thu, 17 Dec 2020 21:04:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rv-0005jW-FO
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rv-0007ww-Ec
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Rv-0006Ud-Ds
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6c67Xpzpx1DnnVBwA7TaEzp5peZzPcmrsQ7QS3mGSjE=; b=NjLUzsO089r1sziRg9QjnaRlWJ
	0tSzWyviq59miU/Sc9fglz+7sNB6puzIukT5FDh/FBi/yjttxcibX/GjFXmnHEbPYRP+hf24YUf40
	V+cwIPiMNK9Vnt3xz0ziYuYGL13shsAjRfNPTNQ68cGHfmwSnbu+Mvd0U6atJLiakAHw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xl: support naming of assignable devices
Message-Id: <E1kq0Rv-0006Ud-Ds@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:35 +0000

commit 93c16ae47baf7e92477c34d434719bfed3ccad84
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:31 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:30 2020 +0000

    xl: support naming of assignable devices
    
    This patch converts libxl to use libxl_pci_bdf_assignable_add/remove/list/
    list_free() rather than libxl_device_pci_assignable_add/remove/list/
    list_free(), which then allows naming of assignable devices to be supported.
    
    With this patch applied 'xl pci-assignable-add' will take an optional '--name'
    parameter, 'xl pci-assignable-remove' can be passed either a BDF or a name and
    'xl pci-assignable-list' will take a optional '--show-names' flag which
    determines whether names are displayed in its output.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/xl/xl_cmdtable.c |  12 ++++--
 tools/xl/xl_pci.c      | 100 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 74 insertions(+), 38 deletions(-)

diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 30e17a2848..bd8af12ff3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -105,21 +105,25 @@ struct cmd_spec cmd_table[] = {
     { "pci-assignable-add",
       &main_pciassignable_add, 0, 1,
       "Make a device assignable for pci-passthru",
-      "<BDF>",
+      "[options] <BDF>",
+      "-n NAME, --name=NAME    Name the assignable device.\n"
       "-h                      Print this help.\n"
     },
     { "pci-assignable-remove",
       &main_pciassignable_remove, 0, 1,
       "Remove a device from being assignable",
-      "[options] <BDF>",
+      "[options] <BDF>|NAME",
       "-h                      Print this help.\n"
       "-r                      Attempt to re-assign the device to the\n"
-      "                        original driver"
+      "                        original driver."
     },
     { "pci-assignable-list",
       &main_pciassignable_list, 0, 0,
       "List all the assignable pci devices",
-      "",
+      "[options]",
+      "-h                      Print this help.\n"
+      "-n, --show-names        Display assignable device names where\n"
+      "                        supplied.\n"
     },
     { "pause",
       &main_pause, 0, 1,
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index 9c24496cb2..eb29b4e08d 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -152,55 +152,68 @@ int main_pciattach(int argc, char **argv)
     return EXIT_SUCCESS;
 }
 
-static void pciassignable_list(void)
+static void pciassignable_list(bool show_names)
 {
-    libxl_device_pci *pcis;
+    libxl_pci_bdf *pcibdfs;
     int num, i;
 
-    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
 
-    if ( pcis == NULL )
+    if ( pcibdfs == NULL )
         return;
     for (i = 0; i < num; i++) {
-        printf("%04x:%02x:%02x.%01x\n",
-               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
-               pcis[i].bdf.func);
+        libxl_pci_bdf *pcibdf = &pcibdfs[i];
+        char *name = show_names ?
+            libxl_pci_bdf_assignable_bdf2name(ctx, pcibdf) : NULL;
+
+        printf("%04x:%02x:%02x.%01x %s\n",
+               pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
+               name ?: "");
+
+        free(name);
     }
-    libxl_device_pci_assignable_list_free(pcis, num);
+    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
 {
     int opt;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
-        /* No options */
+    static struct option opts[] = {
+        {"show-names", 0, 0, 'n'},
+        COMMON_LONG_OPTS
+    };
+    bool show_names = false;
+
+    SWITCH_FOREACH_OPT(opt, "n", opts, "pci-assignable-list", 0) {
+    case 'n':
+        show_names = true;
+        break;
     }
 
-    pciassignable_list();
+    pciassignable_list(show_names);
     return 0;
 }
 
-static int pciassignable_add(const char *bdf, int rebind)
+static int pciassignable_add(const char *bdf, const char *name, int rebind)
 {
-    libxl_device_pci pci;
+    libxl_pci_bdf pcibdf;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pci);
+    libxl_pci_bdf_init(&pcibdf);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
+    if (xlu_pci_parse_bdf(config, &pcibdf, bdf)) {
         fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
+    if (libxl_pci_bdf_assignable_add(ctx, &pcibdf, name, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pci);
+    libxl_pci_bdf_dispose(&pcibdf);
     xlu_cfg_destroy(config);
 
     return r;
@@ -210,39 +223,58 @@ int main_pciassignable_add(int argc, char **argv)
 {
     int opt;
     const char *bdf = NULL;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
-        /* No options */
+    static struct option opts[] = {
+        {"name", 1, 0, 'n'},
+        COMMON_LONG_OPTS
+    };
+    const char *name = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "n:", opts, "pci-assignable-add", 0) {
+    case 'n':
+        name = optarg;
+        break;
     }
 
     bdf = argv[optind];
 
-    if (pciassignable_add(bdf, 1))
+    if (pciassignable_add(bdf, name, 1))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciassignable_remove(const char *bdf, int rebind)
+static int pciassignable_remove(const char *ident, int rebind)
 {
-    libxl_device_pci pci;
+    libxl_pci_bdf *pcibdf;
     XLU_Config *config;
     int r = 0;
 
-    libxl_device_pci_init(&pci);
-
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pci.bdf, bdf)) {
-        fprintf(stderr, "pci-assignable-remove: malformed BDF \"%s\"\n", bdf);
-        exit(2);
+    pcibdf = libxl_pci_bdf_assignable_name2bdf(ctx, ident);
+    if (!pcibdf) {
+        pcibdf = calloc(1, sizeof(*pcibdf));
+
+        if (!pcibdf) {
+            fprintf(stderr,
+                    "pci-assignable-remove: failed to allocate memory\n");
+            exit(2);
+        }
+
+        libxl_pci_bdf_init(pcibdf);
+        if (xlu_pci_parse_bdf(config, pcibdf, ident)) {
+            fprintf(stderr,
+                    "pci-assignable-remove: malformed BDF '%s'\n", ident);
+            exit(2);
+        }
     }
 
-    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
+    if (libxl_pci_bdf_assignable_remove(ctx, pcibdf, rebind))
         r = 1;
 
-    libxl_device_pci_dispose(&pci);
+    libxl_pci_bdf_dispose(pcibdf);
+    free(pcibdf);
     xlu_cfg_destroy(config);
 
     return r;
@@ -251,7 +283,7 @@ static int pciassignable_remove(const char *bdf, int rebind)
 int main_pciassignable_remove(int argc, char **argv)
 {
     int opt;
-    const char *bdf = NULL;
+    const char *ident = NULL;
     int rebind = 0;
 
     SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
@@ -260,9 +292,9 @@ int main_pciassignable_remove(int argc, char **argv)
         break;
     }
 
-    bdf = argv[optind];
+    ident = argv[optind];
 
-    if (pciassignable_remove(bdf, rebind))
+    if (pciassignable_remove(ident, rebind))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56179.98152 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0S6-0005lC-K4; Thu, 17 Dec 2020 21:04:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56179.98152; Thu, 17 Dec 2020 21:04:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0S6-0005l4-Gv; Thu, 17 Dec 2020 21:04:46 +0000
Received: by outflank-mailman (input) for mailman id 56179;
 Thu, 17 Dec 2020 21:04:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0S5-0005kv-KU
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0S5-0007xA-J7
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0S5-0006W0-Hy
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=SzgfBQQHgGgxp7VKS+ffHZMSa6C7zfrsF9tG+w+UtqY=; b=C8wno/cwvO3P6X3NpbeGT0WNgU
	GtMoAAzTflfCDT0I12HEQ4aQddbMokFD37l954k50UcD2ISQQGdEniYPwMBjKAN13PmABcR9fGE2x
	gqtqAukcsaK4H8mYz5ocMFSUr8jQTQ+f8216GtiufoDLprKfEEk93UaVrh2FtPiol/sw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING
Message-Id: <E1kq0S5-0006W0-Hy@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:45 +0000

commit e1141654c3745588f9f13e8cf7de19cdb987ae5d
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:32 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:34 2020 +0000

    docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING
    
    Since assignable devices can be named, a subsequent patch will support use
    of a PCI_SPEC_STRING containing a 'name' parameter instead of a 'bdf'. In
    this case the name will be used to look up the 'bdf' in the list of assignable
    (or assigned) devices.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index 4dd73bc498..db3360307c 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -51,7 +51,7 @@ is not specified, or if it is specified with an empty value (whether
 positionally or explicitly).
 
 B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
-B<bdf> will be ignored.
+B<bdf> or B<name> will be ignored.
 
 =head1 Positional Parameters
 
@@ -70,7 +70,11 @@ B<*> to indicate all functions of a multi-function device.
 
 =item Default Value
 
-None. This parameter is mandatory as it identifies the device.
+None. This parameter is mandatory in its positional form. As a non-positional
+parameter it is also mandatory unless a B<name> parameter is present, in
+which case B<bdf> must not be present since the B<name> will be used to find
+the B<bdf> in the list of assignable devices. See L<xl(1)> for more information
+on naming assignable devices.
 
 =back
 
@@ -194,4 +198,21 @@ B<NOTE>: This overrides the global B<rdm> option.
 
 =back
 
+=item B<name>=I<STRING>
+
+=over 4
+
+=item Description
+
+This is the name given when the B<BDF> was made assignable. See L<xl(1)> for
+more information on naming assignable devices.
+
+=item Default Value
+
+None. This parameter must not be present if a B<bdf> parameter is present.
+If a B<bdf> parameter is not present then B<name> is mandatory as it is
+required to look up the B<BDF> in the list of assignable devices.
+
+=back
+
 =back
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:04:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:04:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56180.98156 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0SG-0005mc-Ls; Thu, 17 Dec 2020 21:04:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56180.98156; Thu, 17 Dec 2020 21:04:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0SG-0005mU-Ia; Thu, 17 Dec 2020 21:04:56 +0000
Received: by outflank-mailman (input) for mailman id 56180;
 Thu, 17 Dec 2020 21:04:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SF-0005mK-NI
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SF-0007xI-MV
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SF-0006XH-Lt
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:04:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cN6SqvIIZSDy2RsUavmoM6V5excLhw4Rx4apVKg3IdM=; b=Xw0/mzLdlVs66+P4boj9dDG6Df
	yZ+9cr3SGtatFv9G7Ls2g/N7xtWHLui4hReLUkITKOufunslywmjcBw+mMMVbgYX+NcwOUsh4a5mx
	bBZdZNReL2/XOhib+r7DrqKulF81ZyAnBAyK5VXjWAYvO6WaLzmQQHTp0JzeEDIsSG0A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] libxl / libxlu: support 'xl pci-attach/detach' by name
Message-Id: <E1kq0SF-0006XH-Lt@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:04:55 +0000

commit 8bf0fab14256057bbd145563151814300476bb28
Author:     Paul Durrant <pdurrant@amazon.com>
AuthorDate: Tue Dec 8 19:30:33 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Tue Dec 15 16:24:34 2020 +0000

    libxl / libxlu: support 'xl pci-attach/detach' by name
    
    This patch adds a 'name' field into the idl for 'libxl_device_pci' and
    libxlu_pci_parse_spec_string() is modified to parse the new 'name'
    parameter of PCI_SPEC_STRING detailed in the updated documention in
    xl-pci-configuration(5).
    
    If the 'name' field is non-NULL then both libxl_device_pci_add() and
    libxl_device_pci_remove() will use it to look up the device BDF in
    the list of assignable devices.
    
    Signed-off-by: Paul Durrant <pdurrant@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 tools/include/libxl.h            |  6 ++++
 tools/libs/light/libxl_pci.c     | 67 +++++++++++++++++++++++++++++++++++++---
 tools/libs/light/libxl_types.idl |  1 +
 tools/libs/util/libxlu_pci.c     |  7 ++++-
 4 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index fda611f889..90a7aa9b73 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -476,6 +476,12 @@
  */
 #define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
 
+/*
+ * LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of
+ * libxl_device_pci is defined.
+ */
+#define LIBXL_HAVE_DEVICE_PCI_NAME 1
+
 /*
  * libxl ABI compatibility
  *
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index e11574e73f..5d83db2a59 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -60,6 +60,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             int num,
                                             const libxl_device_pci *pci)
 {
+    if (pci->name) {
+        flexarray_append(back, GCSPRINTF("name-%d", num));
+        flexarray_append(back, GCSPRINTF("%s", pci->name));
+    }
     flexarray_append(back, GCSPRINTF("key-%d", num));
     flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
@@ -284,6 +288,7 @@ retry_transaction:
 
 retry_transaction2:
     t = xs_transaction_start(ctx->xsh);
+    xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i));
@@ -322,6 +327,12 @@ retry_transaction2:
             xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
+        tmppath = GCSPRINTF("%s/name-%d", be_path, j);
+        tmp = libxl__xs_read(gc, t, tmppath);
+        if (tmp) {
+            xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp));
+            xs_rm(ctx->xsh, t, tmppath);
+        }
     }
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
@@ -1610,6 +1621,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
+    if (pci->name) {
+        libxl_pci_bdf *pcibdf =
+            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
+
+        if (!pcibdf) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
+             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+
+        libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf);
+        libxl_pci_bdf_dispose(pcibdf);
+        free(pcibdf);
+    }
+
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
         rc = xc_test_assign_device(ctx->xch, domid,
                                    pci_encode_bdf(&pci->bdf));
@@ -1758,11 +1786,19 @@ static void device_pci_add_done(libxl__egc *egc,
     libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
-        LOGD(ERROR, domid,
-             "libxl__device_pci_add  failed for "
-             "PCI device %x:%x:%x.%x (rc %d)",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
-             rc);
+        if (pci->name) {
+            LOGD(ERROR, domid,
+                 "libxl__device_pci_add failed for "
+                 "PCI device '%s' (rc %d)",
+                 pci->name,
+                 rc);
+        } else {
+            LOGD(ERROR, domid,
+                 "libxl__device_pci_add failed for "
+                 "PCI device %x:%x:%x.%x (rc %d)",
+                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                 rc);
+        }
         pci_info_xs_remove(gc, &pci->bdf, "domid");
     }
     libxl_device_pci_dispose(pci);
@@ -2279,6 +2315,23 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
+    if (pci->name) {
+        libxl_pci_bdf *pcibdf =
+            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
+
+        if (!pcibdf) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
+             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+
+        libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf);
+        libxl_pci_bdf_dispose(pcibdf);
+        free(pcibdf);
+    }
+
     prs->orig_vdev = pci->vdevfn & ~7U;
 
     if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
@@ -2413,6 +2466,10 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
 
+    s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr));
+    if (s)
+        pci->name = strdup(s);
+
     return 0;
 }
 
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 21a2cf5c1c..32cc99beff 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -779,6 +779,7 @@ libxl_pci_bdf = Struct("pci_bdf", [
 
 libxl_device_pci = Struct("device_pci", [
     ("bdf", libxl_pci_bdf),
+    ("name", string),
     ("vdevfn", uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index a8b6ce5427..543a1f80e9 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -151,6 +151,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
 {
     const char *ptr = str;
     bool bdf_present = false;
+    bool name_present = false;
     int ret;
 
     /* Attempt to parse 'bdf' as positional parameter */
@@ -193,6 +194,10 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
             pcidev->power_mgmt = atoi(val);
         } else if (!strcmp(key, "rdm_policy")) {
             ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
+        } else if (!strcmp(key, "name")) {
+            name_present = true;
+            pcidev->name = strdup(val);
+            if (!pcidev->name) ret = ERROR_NOMEM;
         } else {
             XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
             ret = ERROR_INVAL;
@@ -205,7 +210,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
             return ret;
     }
 
-    if (!bdf_present)
+    if (!(bdf_present ^ name_present))
         return ERROR_INVAL;
 
     return 0;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:05:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:05:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56181.98161 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0SQ-0005oY-P2; Thu, 17 Dec 2020 21:05:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56181.98161; Thu, 17 Dec 2020 21:05:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0SQ-0005oM-La; Thu, 17 Dec 2020 21:05:06 +0000
Received: by outflank-mailman (input) for mailman id 56181;
 Thu, 17 Dec 2020 21:05:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SP-0005oA-Qf
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SP-0007xt-Ps
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SP-0006Yi-Oi
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OFbUrT45kktDhcXv34lc3YWTSq76/kDR2krenVOG+tQ=; b=kUifnEERA+8hIbuKbrkJwNFPjD
	8F6xl/Wlz7bOUYvtXiguFwSqzxH/o7Zc6ntKiNm5VBOtfQku28nuSJFSy3DCu+WafegNgmShwd725
	MbKQUvZb2qYaOLm0vgFX/qNhn640S77AobOi1gJiseae1uOONxI9P6wVrZ29eL3QT8tk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86: clobber registers in switch_stack_and_jump() when !LIVEPATCH
Message-Id: <E1kq0SP-0006Yi-Oi@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:05:05 +0000

commit 033a80677087b322789d2748e83b764545f76c6b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:41:46 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:41:46 2020 +0100

    x86: clobber registers in switch_stack_and_jump() when !LIVEPATCH
    
    In order to have the same effect on registers as a call to
    check_for_livepatch_work() may have, clobber all call-clobbered
    registers in debug builds.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/include/asm-x86/current.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 4d8822f78c..231994a245 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -120,6 +120,14 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 
 #ifdef CONFIG_LIVEPATCH
 # define CHECK_FOR_LIVEPATCH_WORK "call check_for_livepatch_work;"
+#elif defined(CONFIG_DEBUG)
+/* Mimic the clobbering effect a call has on registers. */
+# define CHECK_FOR_LIVEPATCH_WORK \
+    "mov $0x1234567890abcdef, %%rax\n\t" \
+    "mov %%rax, %%rcx; mov %%rax, %%rdx\n\t" \
+    "mov %%rax, %%rsi; mov %%rax, %%rdi\n\t" \
+    "mov %%rax, %%r8; mov %%rax, %%r9\n\t" \
+    "mov %%rax, %%r10; mov %%rax, %%r11\n\t"
 #else
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:05:19 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:05:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56182.98164 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Sa-0005ps-QF; Thu, 17 Dec 2020 21:05:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56182.98164; Thu, 17 Dec 2020 21:05:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Sa-0005pk-NB; Thu, 17 Dec 2020 21:05:16 +0000
Received: by outflank-mailman (input) for mailman id 56182;
 Thu, 17 Dec 2020 21:05:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SZ-0005pZ-Tt
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SZ-0007y0-TA
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0SZ-0006a1-SR
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OYrbzFaiWB2OL8M9580otqi4pinDu2ijMnj/RwNMRbs=; b=KdjDybxUGHz2eQdux0o363Za/F
	G+VNgnfscuyFGupKoTShRGxx0+1tdemilsvfBg4ld4qtAUipBhkWURmEYWAU+RD4WnaMV6iYDpSJb
	40EdapgKGi4M9MeKUNXTLbRobNU/7EoK6gNunByJE1P2Xhs0lW0LTbDJql1Rwp2ZNVlE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/PV: avoid double stack reset during schedule tail handling
Message-Id: <E1kq0SZ-0006a1-SR@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:05:15 +0000

commit 2c2c941686d2aedac0f09b6546c844c391c0f7e8
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:42:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:42:50 2020 +0100

    x86/PV: avoid double stack reset during schedule tail handling
    
    Invoking check_wakeup_from_wait() from assembly allows the new
    continue_pv_domain() to replace the prior continue_nonidle_domain() as
    the tail hook, eliminating an extra reset_stack_and_jump().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
---
 xen/arch/x86/pv/domain.c        | 9 ++-------
 xen/arch/x86/x86_64/entry.S     | 5 ++++-
 xen/include/asm-x86/asm_defns.h | 1 -
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 1a607f856e..23d6009143 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -110,12 +110,6 @@ static int parse_pcid(const char *s)
     return rc;
 }
 
-static void noreturn continue_nonidle_domain(void)
-{
-    check_wakeup_from_wait();
-    reset_stack_and_jump(ret_from_intr);
-}
-
 static int setup_compat_l4(struct vcpu *v)
 {
     struct page_info *pg;
@@ -341,13 +335,14 @@ void pv_domain_destroy(struct domain *d)
     FREE_XENHEAP_PAGE(d->arch.pv.gdt_ldt_l1tab);
 }
 
+void noreturn continue_pv_domain(void);
 
 int pv_domain_initialise(struct domain *d)
 {
     static const struct arch_csw pv_csw = {
         .from = paravirt_ctxt_switch_from,
         .to   = paravirt_ctxt_switch_to,
-        .tail = continue_nonidle_domain,
+        .tail = continue_pv_domain,
     };
     int rc = -ENOMEM;
 
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 000eb9722b..526c388458 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -557,8 +557,10 @@ ENTRY(dom_crash_sync_extable)
         .text
 
 /* No special register assumptions. */
-ENTRY(ret_from_intr)
 #ifdef CONFIG_PV
+ENTRY(continue_pv_domain)
+        call  check_wakeup_from_wait
+ret_from_intr:
         GET_CURRENT(bx)
         testb $3, UREGS_cs(%rsp)
         jz    restore_all_xen
@@ -567,6 +569,7 @@ ENTRY(ret_from_intr)
         je    test_all_events
         jmp   compat_test_all_events
 #else
+ret_from_intr:
         ASSERT_CONTEXT_IS_XEN
         jmp   restore_all_xen
 #endif
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index b42a19b654..774a294d15 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -23,7 +23,6 @@ asm ( "\t.equ CONFIG_INDIRECT_THUNK, "
 #include <asm/indirect_thunk_asm.h>
 
 #ifndef __ASSEMBLY__
-void ret_from_intr(void);
 
 /*
  * This output constraint should be used for any inline asm which has a "call"
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:05:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:05:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56183.98168 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Sk-0005rC-S2; Thu, 17 Dec 2020 21:05:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56183.98168; Thu, 17 Dec 2020 21:05:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Sk-0005r4-Oo; Thu, 17 Dec 2020 21:05:26 +0000
Received: by outflank-mailman (input) for mailman id 56183;
 Thu, 17 Dec 2020 21:05:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Sk-0005qy-0u
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Sk-0007y8-0D
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Sj-0006bm-Vk
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=REdthwJB3zHexSlBZzCCypnVckZsmnQd/q7TsHnUU6c=; b=uXNDmGJyY8GzyHp6+NCMStn+qp
	wfrlvnyVSvQfoAK3/mXbhKZjq8cMWvgUoUCdH6xl+K2+xijxFCCaAbEn8fufgAcihvR0dPX81PVou
	9X2kUxYaNSzJ1GznCfXqgbqOOOBawJZMuc/sKJ0e6ZrOZEKlsEKR5RzM0lP3GLB3NUsg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] livepatch: adjust a stale comment
Message-Id: <E1kq0Sj-0006bm-Vk@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:05:25 +0000

commit 7dcaffce645bde8b59e127df640b769885c2ffe4
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:43:32 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:43:32 2020 +0100

    livepatch: adjust a stale comment
    
    As of 005de45c887e ("xen: do live patching only from main idle loop")
    the comment ahead of livepatch_do_action() has been stale.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 xen/common/livepatch.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 81ceafce98..7118551b27 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1392,8 +1392,8 @@ static inline bool was_action_consistent(const struct payload *data, livepatch_f
 }
 
 /*
- * This function is executed having all other CPUs with no deep stack (we may
- * have cpu_idle on it) and IRQs disabled.
+ * This function is executed having all other CPUs with no deep stack (when
+ * idle) and IRQs disabled.
  */
 static void livepatch_do_action(void)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:05:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:05:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56184.98172 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Su-0005sc-TW; Thu, 17 Dec 2020 21:05:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56184.98172; Thu, 17 Dec 2020 21:05:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0Su-0005sV-QV; Thu, 17 Dec 2020 21:05:36 +0000
Received: by outflank-mailman (input) for mailman id 56184;
 Thu, 17 Dec 2020 21:05:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Su-0005sM-3n
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Su-0007yI-36
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0Su-0006eu-2L
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=fJ+vFSC4gSmXtUmZh7z/suy0vbIjKAdSIh5d5SSIa+0=; b=SHJCZTs+5Nngo4lEkxMbo7kamz
	gu2HSZpOLckbTWP3jAiPOa/EaOI0TTGWU976YCAPBRkGVVDXZvL/sP8KDZHyvmMp9mucqKOqDW2Nh
	AZsUBOeGjvNGdIG3U3MJQNJH91LsgL3spPi2L5Pn0tYSxQrXKZErs3/EaB/z4aUrhznY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/p2m: set_shared_p2m_entry() is MEM_SHARING-only
Message-Id: <E1kq0Su-0006eu-2L@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:05:36 +0000

commit 5a324e1c39b6b78496dc73c222c9874302c2423c
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Wed Dec 16 16:44:18 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 16 16:44:18 2020 +0100

    x86/p2m: set_shared_p2m_entry() is MEM_SHARING-only
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Tamas K Lengyel <tamas@tklengyel.com>
---
 xen/arch/x86/mm/p2m.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index db6cc2202d..cd0812db18 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1466,6 +1466,8 @@ int clear_identity_p2m_entry(struct domain *d, unsigned long gfn_l)
     return ret;
 }
 
+#ifdef CONFIG_MEM_SHARING
+
 /* Returns: 0 for success, -errno for failure */
 int set_shared_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn)
 {
@@ -1504,7 +1506,10 @@ int set_shared_p2m_entry(struct domain *d, unsigned long gfn_l, mfn_t mfn)
     return rc;
 }
 
+#endif /* CONFIG_MEM_SHARING */
+
 #ifdef CONFIG_HVM
+
 static struct p2m_domain *
 p2m_getlru_nestedp2m(struct domain *d, struct p2m_domain *p2m)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 21:05:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 21:05:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56185.98176 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0T4-0005uD-VW; Thu, 17 Dec 2020 21:05:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56185.98176; Thu, 17 Dec 2020 21:05:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq0T4-0005u6-SF; Thu, 17 Dec 2020 21:05:46 +0000
Received: by outflank-mailman (input) for mailman id 56185;
 Thu, 17 Dec 2020 21:05:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0T4-0005tx-99
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0T4-0007yR-8L
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq0T4-0006fi-6c
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 21:05:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JlQ8vkd5imRFgVC4EK0SwQyV8Q8MnwVdY5XcRbkJNws=; b=gTW/o9jnokbW6RVD2jMbrNbCbN
	xn9dEL3/BhUT1aCpqMrky1XOWeV+80hxUNVoH6qdah7YYhrcfmvvm81hoxXrognWzY8TaEvkq2ARH
	nJ+7nsU+uSlrTSjIAIOUoQiy67NBTKNUDysh/QTNiYSiitE2iDVRFzdysIktdF0vJyvE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] Revert patches that break libxl API
Message-Id: <E1kq0T4-0006fi-6c@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 21:05:46 +0000

commit ac6a0af3870ba0f7ffb16af3e41827b0a53f88b0
Author:     Wei Liu <wl@xen.org>
AuthorDate: Wed Dec 16 17:48:04 2020 +0000
Commit:     Wei Liu <wl@xen.org>
CommitDate: Wed Dec 16 18:03:26 2020 +0000

    Revert patches that break libxl API
    
    This patch reverts eight patches from staging.
    
    The offending patch is the one that introduced libxl_pci_bdf (last one
    in the list). The rest depend on that patch so they are also reverted.
    
    8bf0fab14256 "libxl / libxlu: support 'xl pci-attach/detach' by name"
    e1141654c374 "docs/man: modify xl-pci-configuration(5) to add 'name' field to PCI_SPEC_STRING"
    93c16ae47baf "xl: support naming of assignable devices"
    5ab684cb3e4d "libxl: introduce libxl_pci_bdf_assignable_add/remove/list/list_free(), ..."
    66c2fbc6e82b "libxl: convert internal functions in libxl_pci.c..."
    f73c5dd56d78 "docs/man: modify xl(1) in preparation for naming of assignable devices"
    96ed6ff29741 "libxlu: introduce xlu_pci_parse_spec_string()"
    929f23114061 "libxl: introduce 'libxl_pci_bdf' in the idl..."
    
    Signed-off-by: Wei Liu <wl@xen.org>
---
 docs/man/xl-pci-configuration.5.pod  |  25 +-
 docs/man/xl.1.pod.in                 |  19 +-
 tools/golang/xenlight/helpers.gen.go |  77 ++----
 tools/golang/xenlight/types.gen.go   |   8 +-
 tools/include/libxl.h                |  48 +---
 tools/include/libxlutil.h            |   8 +-
 tools/libs/light/libxl_dm.c          |   8 +-
 tools/libs/light/libxl_internal.h    |   3 +-
 tools/libs/light/libxl_pci.c         | 501 +++++++++++------------------------
 tools/libs/light/libxl_types.idl     |  17 +-
 tools/libs/util/libxlu_pci.c         | 359 ++++++++++++-------------
 tools/xl/xl_cmdtable.c               |  16 +-
 tools/xl/xl_parse.c                  |   4 +-
 tools/xl/xl_pci.c                    | 133 ++++------
 tools/xl/xl_sxp.c                    |   4 +-
 15 files changed, 431 insertions(+), 799 deletions(-)

diff --git a/docs/man/xl-pci-configuration.5.pod b/docs/man/xl-pci-configuration.5.pod
index db3360307c..4dd73bc498 100644
--- a/docs/man/xl-pci-configuration.5.pod
+++ b/docs/man/xl-pci-configuration.5.pod
@@ -51,7 +51,7 @@ is not specified, or if it is specified with an empty value (whether
 positionally or explicitly).
 
 B<NOTE>: In context of B<xl pci-detach> (see L<xl(1)>), parameters other than
-B<bdf> or B<name> will be ignored.
+B<bdf> will be ignored.
 
 =head1 Positional Parameters
 
@@ -70,11 +70,7 @@ B<*> to indicate all functions of a multi-function device.
 
 =item Default Value
 
-None. This parameter is mandatory in its positional form. As a non-positional
-parameter it is also mandatory unless a B<name> parameter is present, in
-which case B<bdf> must not be present since the B<name> will be used to find
-the B<bdf> in the list of assignable devices. See L<xl(1)> for more information
-on naming assignable devices.
+None. This parameter is mandatory as it identifies the device.
 
 =back
 
@@ -198,21 +194,4 @@ B<NOTE>: This overrides the global B<rdm> option.
 
 =back
 
-=item B<name>=I<STRING>
-
-=over 4
-
-=item Description
-
-This is the name given when the B<BDF> was made assignable. See L<xl(1)> for
-more information on naming assignable devices.
-
-=item Default Value
-
-None. This parameter must not be present if a B<bdf> parameter is present.
-If a B<bdf> parameter is not present then B<name> is mandatory as it is
-required to look up the B<BDF> in the list of assignable devices.
-
-=back
-
 =back
diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in
index f4779d8fd6..af31d2b572 100644
--- a/docs/man/xl.1.pod.in
+++ b/docs/man/xl.1.pod.in
@@ -1595,23 +1595,19 @@ List virtual network interfaces for a domain.
 
 =over 4
 
-=item B<pci-assignable-list> [I<-n>]
+=item B<pci-assignable-list>
 
 List all the B<BDF> of assignable PCI devices. See
-L<xl-pci-configuration(5)> for more information. If the -n option is
-specified then any name supplied when the device was made assignable
-will also be displayed.
+L<xl-pci-configuration(5)> for more information.
 
 These are devices in the system which are configured to be
 available for passthrough and are bound to a suitable PCI
 backend driver in domain 0 rather than a real driver.
 
-=item B<pci-assignable-add> [I<-n NAME>] I<BDF>
+=item B<pci-assignable-add> I<BDF>
 
 Make the device at B<BDF> assignable to guests. See
-L<xl-pci-configuration(5)> for more information. If the -n option is
-supplied then the assignable device entry will the named with the
-given B<NAME>.
+L<xl-pci-configuration(5)> for more information.
 
 This will bind the device to the pciback driver and assign it to the
 "quarantine domain".  If it is already bound to a driver, it will
@@ -1626,11 +1622,10 @@ not to do this on a device critical to domain 0's operation, such as
 storage controllers, network interfaces, or GPUs that are currently
 being used.
 
-=item B<pci-assignable-remove> [I<-r>] I<BDF>|I<NAME>
+=item B<pci-assignable-remove> [I<-r>] I<BDF>
 
-Make a device non-assignable to guests. The device may be identified
-either by its B<BDF> or the B<NAME> supplied when the device was made
-assignable. See L<xl-pci-configuration(5)> for more information.
+Make the device at B<BDF> not assignable to guests. See
+L<xl-pci-configuration(5)> for more information.
 
 This will at least unbind the device from pciback, and
 re-assign it from the "quarantine domain" back to domain 0.  If the -r
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index b7230f693c..c8605994e7 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1999,41 +1999,6 @@ xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)}
  return nil
  }
 
-// NewPciBdf returns an instance of PciBdf initialized with defaults.
-func NewPciBdf() (*PciBdf, error) {
-var (
-x PciBdf
-xc C.libxl_pci_bdf)
-
-C.libxl_pci_bdf_init(&xc)
-defer C.libxl_pci_bdf_dispose(&xc)
-
-if err := x.fromC(&xc); err != nil {
-return nil, err }
-
-return &x, nil}
-
-func (x *PciBdf) fromC(xc *C.libxl_pci_bdf) error {
- x.Func = byte(xc._func)
-x.Dev = byte(xc.dev)
-x.Bus = byte(xc.bus)
-x.Domain = int(xc.domain)
-
- return nil}
-
-func (x *PciBdf) toC(xc *C.libxl_pci_bdf) (err error){defer func(){
-if err != nil{
-C.libxl_pci_bdf_dispose(xc)}
-}()
-
-xc._func = C.uint8_t(x.Func)
-xc.dev = C.uint8_t(x.Dev)
-xc.bus = C.uint8_t(x.Bus)
-xc.domain = C.int(x.Domain)
-
- return nil
- }
-
 // NewDevicePci returns an instance of DevicePci initialized with defaults.
 func NewDevicePci() (*DevicePci, error) {
 var (
@@ -2049,9 +2014,10 @@ return nil, err }
 return &x, nil}
 
 func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
- if err := x.Bdf.fromC(&xc.bdf);err != nil {
-return fmt.Errorf("converting field Bdf: %v", err)
-}
+ x.Func = byte(xc._func)
+x.Dev = byte(xc.dev)
+x.Bus = byte(xc.bus)
+x.Domain = int(xc.domain)
 x.Vdevfn = uint32(xc.vdevfn)
 x.VfuncMask = uint32(xc.vfunc_mask)
 x.Msitranslate = bool(xc.msitranslate)
@@ -2067,9 +2033,10 @@ if err != nil{
 C.libxl_device_pci_dispose(xc)}
 }()
 
-if err := x.Bdf.toC(&xc.bdf); err != nil {
-return fmt.Errorf("converting field Bdf: %v", err)
-}
+xc._func = C.uint8_t(x.Func)
+xc.dev = C.uint8_t(x.Dev)
+xc.bus = C.uint8_t(x.Bus)
+xc.domain = C.int(x.Domain)
 xc.vdevfn = C.uint32_t(x.Vdevfn)
 xc.vfunc_mask = C.uint32_t(x.VfuncMask)
 xc.msitranslate = C.bool(x.Msitranslate)
@@ -2799,13 +2766,13 @@ if err := x.Nics[i].fromC(&v); err != nil {
 return fmt.Errorf("converting field Nics: %v", err) }
 }
 }
-x.Pcis = nil
-if n := int(xc.num_pcis); n > 0 {
-cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:n:n]
-x.Pcis = make([]DevicePci, n)
-for i, v := range cPcis {
-if err := x.Pcis[i].fromC(&v); err != nil {
-return fmt.Errorf("converting field Pcis: %v", err) }
+x.Pcidevs = nil
+if n := int(xc.num_pcidevs); n > 0 {
+cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n]
+x.Pcidevs = make([]DevicePci, n)
+for i, v := range cPcidevs {
+if err := x.Pcidevs[i].fromC(&v); err != nil {
+return fmt.Errorf("converting field Pcidevs: %v", err) }
 }
 }
 x.Rdms = nil
@@ -2955,13 +2922,13 @@ return fmt.Errorf("converting field Nics: %v", err)
 }
 }
 }
-if numPcis := len(x.Pcis); numPcis > 0 {
-xc.pcis = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcis)*C.sizeof_libxl_device_pci))
-xc.num_pcis = C.int(numPcis)
-cPcis := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcis))[:numPcis:numPcis]
-for i,v := range x.Pcis {
-if err := v.toC(&cPcis[i]); err != nil {
-return fmt.Errorf("converting field Pcis: %v", err)
+if numPcidevs := len(x.Pcidevs); numPcidevs > 0 {
+xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs)*C.sizeof_libxl_device_pci))
+xc.num_pcidevs = C.int(numPcidevs)
+cPcidevs := (*[1<<28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
+for i,v := range x.Pcidevs {
+if err := v.toC(&cPcidevs[i]); err != nil {
+return fmt.Errorf("converting field Pcidevs: %v", err)
 }
 }
 }
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index bc62ae8ce9..b4c5df0f2c 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -707,15 +707,11 @@ ColoCheckpointHost string
 ColoCheckpointPort string
 }
 
-type PciBdf struct {
+type DevicePci struct {
 Func byte
 Dev byte
 Bus byte
 Domain int
-}
-
-type DevicePci struct {
-Bdf PciBdf
 Vdevfn uint32
 VfuncMask uint32
 Msitranslate bool
@@ -900,7 +896,7 @@ CInfo DomainCreateInfo
 BInfo DomainBuildInfo
 Disks []DeviceDisk
 Nics []DeviceNic
-Pcis []DevicePci
+Pcidevs []DevicePci
 Rdms []DeviceRdm
 Dtdevs []DeviceDtdev
 Vfbs []DeviceVfb
diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 90a7aa9b73..3433c950f9 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -463,25 +463,6 @@
  */
 #define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
 
-/*
- * LIBXL_HAVE_PCI_BDF indicates that the 'libxl_pci_bdf' type is defined
- * is embedded in the 'libxl_device_pci' type.
- */
-#define LIBXL_HAVE_PCI_BDF 1
-
-/*
- * LIBXL_HAVE_PCI_ASSIGNABLE_BDF indicates that the
- * libxl_pci_bdf_assignable_add/remove/list/list_free() functions all
- * exist.
- */
-#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
-
-/*
- * LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of
- * libxl_device_pci is defined.
- */
-#define LIBXL_HAVE_DEVICE_PCI_NAME 1
-
 /*
  * libxl ABI compatibility
  *
@@ -2370,9 +2351,9 @@ int libxl_device_events_handler(libxl_ctx *ctx,
                                 LIBXL_EXTERNAL_CALLERS_ONLY;
 
 /*
- * Functions related to making PCI devices with the specified BDF
- * assignable -- that is, bound to the pciback driver, ready to be given to
- * a guest via libxl_pci_device_add.
+ * Functions related to making devices assignable -- that is, bound to
+ * the pciback driver, ready to be given to a guest via
+ * libxl_pci_device_add.
  *
  * - ..._add() will unbind the device from its current driver (if
  * already bound) and re-bind it to pciback; at that point it will be
@@ -2384,31 +2365,16 @@ int libxl_device_events_handler(libxl_ctx *ctx,
  * rebind is non-zero, attempt to assign it back to the driver
  * from whence it came.
  *
- * - ..._list() will return a list of the PCI BDFs available to be
+ * - ..._list() will return a list of the PCI devices available to be
  * assigned.
  *
  * add and remove are idempotent: if the device in question is already
  * added or is not bound, the functions will emit a warning but return
  * SUCCESS.
  */
-int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                 const char *name, int rebind);
-int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                    int rebind);
-libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num);
-void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num);
-libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
-                                                 const char *name);
-char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
-                                        libxl_pci_bdf *pcibdf);
-
-/* Compatibility functions - Use libxl_pci_bdf_assignable_* instead */
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind);
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind);
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
-                                                   int *num);
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci, int rebind);
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num);
 void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num);
 
 /* CPUID handling */
diff --git a/tools/include/libxlutil.h b/tools/include/libxlutil.h
index cdd6aab4f8..92e35c5462 100644
--- a/tools/include/libxlutil.h
+++ b/tools/include/libxlutil.h
@@ -108,16 +108,10 @@ int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs,
    * resulting disk struct is used with libxl.
    */
 
-/*
- * PCI BDF
- */
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str);
-
 /*
  * PCI specification parsing
  */
-int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pci,
-                              const char *str);
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str);
 
 /*
  * RDM parsing
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 1b951b0920..3da83259c0 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -472,10 +472,10 @@ int libxl__domain_device_construct_rdm(libxl__gc *gc,
     for (i = 0; i < d_config->num_pcidevs; i++) {
         unsigned int n, nr_entries;
 
-        seg = d_config->pcidevs[i].bdf.domain;
-        bus = d_config->pcidevs[i].bdf.bus;
-        devfn = PCI_DEVFN(d_config->pcidevs[i].bdf.dev,
-                          d_config->pcidevs[i].bdf.func);
+        seg = d_config->pcidevs[i].domain;
+        bus = d_config->pcidevs[i].bus;
+        devfn = PCI_DEVFN(d_config->pcidevs[i].dev,
+                          d_config->pcidevs[i].func);
         nr_entries = 0;
         rc = libxl__xc_device_get_rdm(gc, 0,
                                       seg, bus, devfn, &nr_entries, &xrdm);
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index 6be7b12e4c..c79523ba92 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4746,11 +4746,10 @@ void libxl__xcinfo2xlinfo(libxl_ctx *ctx,
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
 #define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
-#define COMPARE_BDF(a, b) ((a)->domain == (b)->domain && \
+#define COMPARE_PCI(a, b) ((a)->domain == (b)->domain && \
                            (a)->bus == (b)->bus &&       \
                            (a)->dev == (b)->dev &&       \
                            (a)->func == (b)->func)
-#define COMPARE_PCI(a, b) COMPARE_BDF(&((a)->bdf), &((b)->bdf))
 #define COMPARE_USB(a, b) ((a)->ctrl == (b)->ctrl && \
                            (a)->port == (b)->port)
 #define COMPARE_USBCTRL(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 5d83db2a59..74c2196ae3 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -25,33 +25,26 @@
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
 #define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
-static unsigned int pci_encode_bdf(libxl_pci_bdf *pcibdf)
+static unsigned int pci_encode_bdf(libxl_device_pci *pci)
 {
     unsigned int value;
 
-    value = pcibdf->domain << 16;
-    value |= (pcibdf->bus & 0xff) << 8;
-    value |= (pcibdf->dev & 0x1f) << 3;
-    value |= (pcibdf->func & 0x7);
+    value = pci->domain << 16;
+    value |= (pci->bus & 0xff) << 8;
+    value |= (pci->dev & 0x1f) << 3;
+    value |= (pci->func & 0x7);
 
     return value;
 }
 
-static void pcibdf_struct_fill(libxl_pci_bdf *pcibdf, unsigned int domain,
-                               unsigned int bus, unsigned int dev,
-                               unsigned int func)
-{
-    pcibdf->domain = domain;
-    pcibdf->bus = bus;
-    pcibdf->dev = dev;
-    pcibdf->func = func;
-}
-
 static void pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
                             unsigned int bus, unsigned int dev,
                             unsigned int func, unsigned int vdevfn)
 {
-    pcibdf_struct_fill(&pci->bdf, domain, bus, dev, func);
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
     pci->vdevfn = vdevfn;
 }
 
@@ -60,14 +53,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
                                             int num,
                                             const libxl_device_pci *pci)
 {
-    if (pci->name) {
-        flexarray_append(back, GCSPRINTF("name-%d", num));
-        flexarray_append(back, GCSPRINTF("%s", pci->name));
-    }
     flexarray_append(back, GCSPRINTF("key-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     flexarray_append(back, GCSPRINTF("dev-%d", num));
-    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
+    flexarray_append(back, GCSPRINTF(PCI_BDF, pci->domain, pci->bus, pci->dev, pci->func));
     if (pci->vdevfn)
         flexarray_append_pair(back, GCSPRINTF("vdevfn-%d", num), GCSPRINTF("%x", pci->vdevfn));
     flexarray_append(back, GCSPRINTF("opts-%d", num));
@@ -261,8 +250,8 @@ static int libxl__device_pci_remove_xenstore(libxl__gc *gc, uint32_t domid, libx
         unsigned int domain = 0, bus = 0, dev = 0, func = 0;
         xsdev = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/dev-%d", be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        if (domain == pci->bdf.domain && bus == pci->bdf.bus &&
-            pci->bdf.dev == dev && pci->bdf.func == func) {
+        if (domain == pci->domain && bus == pci->bus &&
+            pci->dev == dev && pci->func == func) {
             break;
         }
     }
@@ -288,7 +277,6 @@ retry_transaction:
 
 retry_transaction2:
     t = xs_transaction_start(ctx->xsh);
-    xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i));
     xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i));
@@ -327,12 +315,6 @@ retry_transaction2:
             xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
-        tmppath = GCSPRINTF("%s/name-%d", be_path, j);
-        tmp = libxl__xs_read(gc, t, tmppath);
-        if (tmp) {
-            xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp));
-            xs_rm(ctx->xsh, t, tmppath);
-        }
     }
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
@@ -368,8 +350,8 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num,
 }
 
 /* Write the standard BDF into the sysfs path given by sysfs_path. */
-static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
-                           libxl_pci_bdf *pcibdf)
+static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path,
+                           libxl_device_pci *pci)
 {
     int rc, fd;
     char *buf;
@@ -380,8 +362,8 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
         return ERROR_FAIL;
     }
 
-    buf = GCSPRINTF(PCI_BDF, pcibdf->domain, pcibdf->bus,
-                    pcibdf->dev, pcibdf->func);
+    buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus,
+                    pci->dev, pci->func);
     rc = write(fd, buf, strlen(buf));
     /* Annoying to have two if's, but we need the errno */
     if (rc < 0)
@@ -396,22 +378,22 @@ static int sysfs_write_bdf(libxl__gc *gc, const char *sysfs_path,
 
 #define PCI_INFO_PATH "/libxl/pci"
 
-static char *pci_info_xs_path(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node)
 {
     return node ?
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH"/%s",
-                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
+                  pci->domain, pci->bus, pci->dev, pci->func,
                   node) :
         GCSPRINTF(PCI_INFO_PATH"/"PCI_BDF_XSPATH,
-                  pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
+                  pci->domain, pci->bus, pci->dev, pci->func);
 }
 
 
-static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static int pci_info_xs_write(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node, const char *val)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
     int rc = libxl__xs_printf(gc, XBT_NULL, path, "%s", val);
 
     if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path);
@@ -419,28 +401,28 @@ static int pci_info_xs_write(libxl__gc *gc, libxl_pci_bdf *pcibdf,
     return rc;
 }
 
-static char *pci_info_xs_read(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static char *pci_info_xs_read(libxl__gc *gc, libxl_device_pci *pci,
                               const char *node)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
 
     return libxl__xs_read(gc, XBT_NULL, path);
 }
 
-static void pci_info_xs_remove(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static void pci_info_xs_remove(libxl__gc *gc, libxl_device_pci *pci,
                                const char *node)
 {
-    char *path = pci_info_xs_path(gc, pcibdf, node);
+    char *path = pci_info_xs_path(gc, pci, node);
     libxl_ctx *ctx = libxl__gc_owner(gc);
 
     /* Remove the xenstore entry */
     xs_rm(ctx->xsh, XBT_NULL, path);
 }
 
-libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
+libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
 {
     GC_INIT(ctx);
-    libxl_pci_bdf *pcibdfs = NULL, *new;
+    libxl_device_pci *pcis = NULL, *new;
     struct dirent *de;
     DIR *dir;
 
@@ -461,15 +443,15 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
         if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
             continue;
 
-        new = realloc(pcibdfs, ((*num) + 1) * sizeof(*new));
+        new = realloc(pcis, ((*num) + 1) * sizeof(*new));
         if (NULL == new)
             continue;
 
-        pcibdfs = new;
-        new = pcibdfs + *num;
+        pcis = new;
+        new = pcis + *num;
 
-        libxl_pci_bdf_init(new);
-        pcibdf_struct_fill(new, dom, bus, dev, func);
+        libxl_device_pci_init(new);
+        pci_struct_fill(new, dom, bus, dev, func, 0);
 
         if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
             continue;
@@ -480,32 +462,32 @@ libxl_pci_bdf *libxl_pci_bdf_assignable_list(libxl_ctx *ctx, int *num)
     closedir(dir);
 out:
     GC_FREE;
-    return pcibdfs;
+    return pcis;
 }
 
-void libxl_pci_bdf_assignable_list_free(libxl_pci_bdf *list, int num)
+void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
 {
     int i;
 
     for (i = 0; i < num; i++)
-        libxl_pci_bdf_dispose(&list[i]);
+        libxl_device_pci_dispose(&list[i]);
 
     free(list);
 }
 
 /* Unbind device from its current driver, if any.  If driver_path is non-NULL,
  * store the path to the original driver in it. */
-static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
+static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci,
                             char **driver_path)
 {
     char * spath, *dp = NULL;
     struct stat st;
 
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver",
-                           pcibdf->domain,
-                           pcibdf->bus,
-                           pcibdf->dev,
-                           pcibdf->func);
+                           pci->domain,
+                           pci->bus,
+                           pci->dev,
+                           pci->func);
     if ( !lstat(spath, &st) ) {
         /* Find the canonical path to the driver. */
         dp = libxl__zalloc(gc, PATH_MAX);
@@ -519,7 +501,7 @@ static int sysfs_dev_unbind(libxl__gc *gc, libxl_pci_bdf *pcibdf,
 
         /* Unbind from the old driver */
         spath = GCSPRINTF("%s/unbind", dp);
-        if ( sysfs_write_bdf(gc, spath, pcibdf) < 0 ) {
+        if ( sysfs_write_bdf(gc, spath, pci) < 0 ) {
             LOGE(ERROR, "Couldn't unbind device");
             return -1;
         }
@@ -535,7 +517,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_vendor_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/vendor",
-                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_vendor;
 
@@ -543,7 +525,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have vendor attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_vendor);
@@ -551,7 +533,7 @@ static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read vendor of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
@@ -562,7 +544,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
 {
     char *pci_device_device_path =
             GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/device",
-                      pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                      pci->domain, pci->bus, pci->dev, pci->func);
     uint16_t read_items;
     uint16_t pci_device_device;
 
@@ -570,7 +552,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have device attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
     read_items = fscanf(f, "0x%hx\n", &pci_device_device);
@@ -578,7 +560,7 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, libxl_device_pci *pci)
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read device of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         return 0xffff;
     }
 
@@ -589,14 +571,14 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
                                unsigned long *class)
 {
     char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-                     pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                     pci->domain, pci->bus, pci->dev, pci->func);
     int read_items, ret = 0;
 
     FILE *f = fopen(pci_device_class_path, "r");
     if (!f) {
         LOGE(ERROR,
              "pci device "PCI_BDF" does not have class attribute",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
         goto out;
     }
@@ -605,7 +587,7 @@ static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pci,
     if (read_items != 1) {
         LOGE(ERROR,
              "cannot read class of pci device "PCI_BDF,
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         ret = ERROR_FAIL;
     }
 
@@ -657,8 +639,8 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc,
  * already exist.
  */
 
-/* Scan through /sys/.../pciback/slots looking for BDF */
-static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+/* Scan through /sys/.../pciback/slots looking for pci's BDF */
+static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci)
 {
     FILE *f;
     int rc = 0;
@@ -672,10 +654,10 @@ static int pciback_dev_has_slot(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     }
 
     while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) == 4) {
-        if (dom == pcibdf->domain
-            && bus == pcibdf->bus
-            && dev == pcibdf->dev
-            && func == pcibdf->func) {
+        if (dom == pci->domain
+            && bus == pci->bus
+            && dev == pci->dev
+            && func == pci->func) {
             rc = 1;
             goto out;
         }
@@ -685,7 +667,7 @@ out:
     return rc;
 }
 
-static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci)
 {
     char * spath;
     int rc;
@@ -701,8 +683,8 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     }
 
     spath = GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF,
-                      pcibdf->domain, pcibdf->bus,
-                      pcibdf->dev, pcibdf->func);
+                      pci->domain, pci->bus,
+                      pci->dev, pci->func);
     rc = lstat(spath, &st);
 
     if( rc == 0 )
@@ -713,40 +695,40 @@ static int pciback_dev_is_assigned(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     return -1;
 }
 
-static int pciback_dev_assign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci)
 {
     int rc;
 
-    if ( (rc = pciback_dev_has_slot(gc, pcibdf)) < 0 ) {
+    if ( (rc = pciback_dev_has_slot(gc, pci)) < 0 ) {
         LOGE(ERROR, "Error checking for pciback slot");
         return ERROR_FAIL;
     } else if (rc == 0) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot",
-                             pcibdf) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't bind device to pciback!");
             return ERROR_FAIL;
         }
     }
 
-    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pcibdf) < 0 ) {
+    if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) {
         LOGE(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
     return 0;
 }
 
-static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
+static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci)
 {
     /* Remove from pciback */
-    if ( sysfs_dev_unbind(gc, pcibdf, NULL) < 0 ) {
+    if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) {
         LOG(ERROR, "Couldn't unbind device!");
         return ERROR_FAIL;
     }
 
     /* Remove slot if necessary */
-    if ( pciback_dev_has_slot(gc, pcibdf) > 0 ) {
+    if ( pciback_dev_has_slot(gc, pci) > 0 ) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot",
-                             pcibdf) < 0 ) {
+                             pci) < 0 ) {
             LOGE(ERROR, "Couldn't remove pciback slot");
             return ERROR_FAIL;
         }
@@ -754,10 +736,9 @@ static int pciback_dev_unassign(libxl__gc *gc, libxl_pci_bdf *pcibdf)
     return 0;
 }
 
-static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
-                                         libxl_pci_bdf *pcibdf,
-                                         const char *name,
-                                         int rebind)
+static int libxl__device_pci_assignable_add(libxl__gc *gc,
+                                            libxl_device_pci *pci,
+                                            int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     unsigned dom, bus, dev, func;
@@ -765,28 +746,11 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     int rc;
     struct stat st;
 
-    /* Sanitise any name that was passed */
-    if (name) {
-        unsigned int i, n = strlen(name);
-
-        if (n > 64) { /* Reasonable upper bound on name length */
-            LOG(ERROR, "Name too long");
-            return ERROR_FAIL;
-        }
-
-        for (i = 0; i < n; i++) {
-            if (!isgraph(name[i])) {
-                LOG(ERROR, "Names may only include printable characters");
-                return ERROR_FAIL;
-            }
-        }
-    }
-
     /* Local copy for convenience */
-    dom = pcibdf->domain;
-    bus = pcibdf->bus;
-    dev = pcibdf->dev;
-    func = pcibdf->func;
+    dom = pci->domain;
+    bus = pci->bus;
+    dev = pci->dev;
+    func = pci->func;
 
     /* See if the device exists */
     spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
@@ -796,17 +760,17 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     }
 
     /* Check to see if it's already assigned to pciback */
-    rc = pciback_dev_is_assigned(gc, pcibdf);
+    rc = pciback_dev_is_assigned(gc, pci);
     if ( rc < 0 ) {
         return ERROR_FAIL;
     }
     if ( rc ) {
         LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func);
-        goto name;
+        goto quarantine;
     }
 
     /* Check to see if there's already a driver that we need to unbind from */
-    if ( sysfs_dev_unbind(gc, pcibdf, &driver_path ) ) {
+    if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) {
         LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver",
             dom, bus, dev, func);
         return ERROR_FAIL;
@@ -815,9 +779,9 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
     /* Store driver_path for rebinding to dom0 */
     if ( rebind ) {
         if ( driver_path ) {
-            pci_info_xs_write(gc, pcibdf, "driver_path", driver_path);
+            pci_info_xs_write(gc, pci, "driver_path", driver_path);
         } else if ( (driver_path =
-                     pci_info_xs_read(gc, pcibdf, "driver_path")) != NULL ) {
+                     pci_info_xs_read(gc, pci, "driver_path")) != NULL ) {
             LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %s",
                 dom, bus, dev, func, driver_path);
         } else {
@@ -825,26 +789,21 @@ static int libxl__pci_bdf_assignable_add(libxl__gc *gc,
                 dom, bus, dev, func);
         }
     } else {
-        pci_info_xs_remove(gc, pcibdf, "driver_path");
+        pci_info_xs_remove(gc, pci, "driver_path");
     }
 
-    if ( pciback_dev_assign(gc, pcibdf) ) {
+    if ( pciback_dev_assign(gc, pci) ) {
         LOG(ERROR, "Couldn't bind device to pciback!");
         return ERROR_FAIL;
     }
 
-name:
-    if (name)
-        pci_info_xs_write(gc, pcibdf, "name", name);
-    else
-        pci_info_xs_remove(gc, pcibdf, "name");
-
+quarantine:
     /*
      * DOMID_IO is just a sentinel domain, without any actual mappings,
      * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
      * unnecessarily denied.
      */
-    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf),
+    rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
                           XEN_DOMCTL_DEV_RDM_RELAXED);
     if ( rc < 0 ) {
         LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -854,33 +813,33 @@ name:
     return 0;
 }
 
-static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
-                                            libxl_pci_bdf *pcibdf,
-                                            int rebind)
+static int libxl__device_pci_assignable_remove(libxl__gc *gc,
+                                               libxl_device_pci *pci,
+                                               int rebind)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int rc;
     char *driver_path;
 
     /* De-quarantine */
-    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pcibdf));
+    rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
     if ( rc < 0 ) {
-        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pcibdf->domain,
-            pcibdf->bus, pcibdf->dev, pcibdf->func);
+        LOG(ERROR, "failed to de-quarantine "PCI_BDF, pci->domain, pci->bus,
+            pci->dev, pci->func);
         return ERROR_FAIL;
     }
 
     /* Unbind from pciback */
-    if ( (rc = pciback_dev_is_assigned(gc, pcibdf)) < 0 ) {
+    if ( (rc = pciback_dev_is_assigned(gc, pci)) < 0 ) {
         return ERROR_FAIL;
     } else if ( rc ) {
-        pciback_dev_unassign(gc, pcibdf);
+        pciback_dev_unassign(gc, pci);
     } else {
         LOG(WARN, "Not bound to pciback");
     }
 
     /* Rebind if necessary */
-    driver_path = pci_info_xs_read(gc, pcibdf, "driver_path");
+    driver_path = pci_info_xs_read(gc, pci, "driver_path");
 
     if ( driver_path ) {
         if ( rebind ) {
@@ -888,12 +847,12 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
 
             if ( sysfs_write_bdf(gc,
                                  GCSPRINTF("%s/bind", driver_path),
-                                 pcibdf) < 0 ) {
+                                 pci) < 0 ) {
                 LOGE(ERROR, "Couldn't bind device to %s", driver_path);
                 return -1;
             }
 
-            pci_info_xs_remove(gc, pcibdf, "driver_path");
+            pci_info_xs_remove(gc, pci, "driver_path");
         }
     } else {
         if ( rebind ) {
@@ -902,87 +861,34 @@ static int libxl__pci_bdf_assignable_remove(libxl__gc *gc,
         }
     }
 
-    pci_info_xs_remove(gc, pcibdf, "name");
-
     return 0;
 }
 
-int libxl_pci_bdf_assignable_add(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                 const char *name, int rebind)
+int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
+                                    int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_add(gc, pcibdf, name, rebind);
+    rc = libxl__device_pci_assignable_add(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
 
-int libxl_pci_bdf_assignable_remove(libxl_ctx *ctx, libxl_pci_bdf *pcibdf,
-                                    int rebind)
+int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
+                                       int rebind)
 {
     GC_INIT(ctx);
     int rc;
 
-    rc = libxl__pci_bdf_assignable_remove(gc, pcibdf, rebind);
+    rc = libxl__device_pci_assignable_remove(gc, pci, rebind);
 
     GC_FREE;
     return rc;
 }
 
-libxl_pci_bdf *libxl_pci_bdf_assignable_name2bdf(libxl_ctx *ctx,
-                                                 const char *name)
-{
-    GC_INIT(ctx);
-    char **bdfs;
-    libxl_pci_bdf *pcibdf = NULL;
-    unsigned int i, n;
-
-    bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n);
-    if (!n)
-        goto out;
-
-    pcibdf = calloc(1, sizeof(*pcibdf));
-    if (!pcibdf)
-        goto out;
-
-    for (i = 0; i < n; i++) {
-        unsigned dom, bus, dev, func;
-        const char *tmp;
-
-        if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4)
-            continue;
-
-        pcibdf_struct_fill(pcibdf, dom, bus, dev, func);
-
-        tmp = pci_info_xs_read(gc, pcibdf, "name");
-        if (tmp && !strcmp(tmp, name))
-            goto out;
-    }
-
-    free(pcibdf);
-    pcibdf = NULL;
-
-out:
-    GC_FREE;
-    return pcibdf;
-}
-
-char *libxl_pci_bdf_assignable_bdf2name(libxl_ctx *ctx,
-                                        libxl_pci_bdf *pcibdf)
-{
-    GC_INIT(ctx);
-    char *name = NULL, *tmp = pci_info_xs_read(gc, pcibdf, "name");
-
-    if (tmp)
-        name = strdup(tmp);
-
-    GC_FREE;
-    return name;
-}
-
 /*
  * This function checks that all functions of a device are bound to pciback
  * driver. It also initialises a bit-mask of which function numbers are present
@@ -1008,11 +914,11 @@ static int pci_multifunction_check(libxl__gc *gc, libxl_device_pci *pci, unsigne
 
         if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
             continue;
-        if ( pci->bdf.domain != dom )
+        if ( pci->domain != dom )
             continue;
-        if ( pci->bdf.bus != bus )
+        if ( pci->bus != bus )
             continue;
-        if ( pci->bdf.dev != dev )
+        if ( pci->dev != dev )
             continue;
 
         path = GCSPRINTF("%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func);
@@ -1061,13 +967,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
     if (pci->vdevfn) {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF_VDEVFN","PCI_OPTIONS,
-                         pci->bdf.domain, pci->bdf.bus, pci->bdf.dev,
-                         pci->bdf.func, pci->vdevfn, pci->msitranslate,
+                         pci->domain, pci->bus, pci->dev,
+                         pci->func, pci->vdevfn, pci->msitranslate,
                          pci->power_mgmt);
     } else {
         libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF","PCI_OPTIONS,
-                         pci->bdf.domain,  pci->bdf.bus, pci->bdf.dev,
-                         pci->bdf.func, pci->msitranslate, pci->power_mgmt);
+                         pci->domain,  pci->bus, pci->dev,
+                         pci->func, pci->msitranslate, pci->power_mgmt);
     }
 
     libxl__qemu_traditional_cmd(gc, domid, "pci-ins");
@@ -1226,10 +1132,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
     libxl__qmp_param_add_string(gc, &args, "driver",
                                 "xen-pci-passthrough");
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           pci->bus, pci->dev, pci->func);
     QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
-                           "%04x:%02x:%02x.%01x", pci->bdf.domain,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           "%04x:%02x:%02x.%01x", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     if (pci->vdevfn) {
         QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
                                PCI_SLOT(pci->vdevfn),
@@ -1317,7 +1223,7 @@ static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
      */
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                         pci->bus, pci->dev, pci->func);
 
     for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
         devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
@@ -1408,8 +1314,8 @@ static void pci_add_dm_done(libxl__egc *egc,
     if (isstubdom)
         starting = false;
 
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                           pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     start = end = flags = size = 0;
     irq = 0;
@@ -1449,8 +1355,8 @@ static void pci_add_dm_done(libxl__egc *egc,
         }
     }
     fclose(f);
-    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
-                                pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                                pci->bus, pci->dev, pci->func);
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -1479,7 +1385,7 @@ static void pci_add_dm_done(libxl__egc *egc,
     /* Don't restrict writes to the PCI config space from this VM */
     if (pci->permissive) {
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
-                             &pci->bdf) < 0 ) {
+                             pci) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
             rc = ERROR_FAIL;
             goto out;
@@ -1495,8 +1401,7 @@ out_no_irq:
             rc = ERROR_FAIL;
             goto out;
         }
-        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(&pci->bdf),
-                             flag);
+        r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
         if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
             rc = ERROR_FAIL;
@@ -1575,21 +1480,17 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static bool is_bdf_assignable(libxl_ctx *ctx, libxl_pci_bdf *pcibdf)
+static bool libxl_pci_assignable(libxl_ctx *ctx, libxl_device_pci *pci)
 {
-    libxl_pci_bdf *pcibdfs;
-    int num, i;
-
-    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
-
-    for (i = 0; i < num; i++) {
-        if (COMPARE_BDF(pcibdf, &pcibdfs[i]))
-            break;
-    }
+    libxl_device_pci *pcis;
+    int num;
+    bool assignable;
 
-    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
+    assignable = is_pci_in_array(pcis, num, pci);
+    libxl_device_pci_assignable_list_free(pcis, num);
 
-    return i < num;
+    return assignable;
 }
 
 static void device_pci_add_stubdom_wait(libxl__egc *egc,
@@ -1621,30 +1522,12 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     pas->starting = starting;
     pas->callback = device_pci_add_stubdom_done;
 
-    if (pci->name) {
-        libxl_pci_bdf *pcibdf =
-            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
-
-        if (!pcibdf) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
-             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
-
-        libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf);
-        libxl_pci_bdf_dispose(pcibdf);
-        free(pcibdf);
-    }
-
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = xc_test_assign_device(ctx->xch, domid,
-                                   pci_encode_bdf(&pci->bdf));
+        rc = xc_test_assign_device(ctx->xch, domid, pci_encode_bdf(pci));
         if (rc) {
             LOGD(ERROR, domid,
                  "PCI device %04x:%02x:%02x.%u %s?",
-                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
+                 pci->domain, pci->bus, pci->dev, pci->func,
                  errno == EOPNOTSUPP ? "cannot be assigned - no IOMMU"
                  : "already assigned to a different guest");
             goto out;
@@ -1654,23 +1537,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
     rc = libxl__device_pci_setdefault(gc, domid, pci, !starting);
     if (rc) goto out;
 
-    if (pci->seize && !pciback_dev_is_assigned(gc, &pci->bdf)) {
-        rc = libxl__pci_bdf_assignable_add(gc, &pci->bdf, NULL, 1);
+    if (pci->seize && !pciback_dev_is_assigned(gc, pci)) {
+        rc = libxl__device_pci_assignable_add(gc, pci, 1);
         if ( rc )
             goto out;
     }
 
-    if (!is_bdf_assignable(ctx, &pci->bdf)) {
+    if (!libxl_pci_assignable(ctx, pci)) {
         LOGD(ERROR, domid, "PCI device %x:%x:%x.%x is not assignable",
-             pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+             pci->domain, pci->bus, pci->dev, pci->func);
         rc = ERROR_FAIL;
         goto out;
     }
 
-    rc = pci_info_xs_write(gc, &pci->bdf, "domid", GCSPRINTF("%u", domid));
+    rc = pci_info_xs_write(gc, pci, "domid", GCSPRINTF("%u", domid));
     if (rc) goto out;
 
-    libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
@@ -1751,13 +1634,13 @@ static void device_pci_add_stubdom_done(libxl__egc *egc,
         pci->vfunc_mask &= pfunc_mask;
         /* so now vfunc_mask == pfunc_mask */
     }else{
-        pfunc_mask = (1 << pci->bdf.func);
+        pfunc_mask = (1 << pci->func);
     }
 
     for (rc = 0, i = 7; i >= 0; --i) {
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->bdf.func = i;
+                pci->func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 /* if not passing through multiple devices in a block make
@@ -1786,20 +1669,12 @@ static void device_pci_add_done(libxl__egc *egc,
     libxl_device_pci *pci = &pas->pci;
 
     if (rc) {
-        if (pci->name) {
-            LOGD(ERROR, domid,
-                 "libxl__device_pci_add failed for "
-                 "PCI device '%s' (rc %d)",
-                 pci->name,
-                 rc);
-        } else {
-            LOGD(ERROR, domid,
-                 "libxl__device_pci_add failed for "
-                 "PCI device %x:%x:%x.%x (rc %d)",
-                 pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
-                 rc);
-        }
-        pci_info_xs_remove(gc, &pci->bdf, "domid");
+        LOGD(ERROR, domid,
+             "libxl__device_pci_add  failed for "
+             "PCI device %x:%x:%x.%x (rc %d)",
+             pci->domain, pci->bus, pci->dev, pci->func,
+             rc);
+        pci_info_xs_remove(gc, pci, "domid");
     }
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -1866,8 +1741,8 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
     state = libxl__xs_read(gc, XBT_NULL, path);
     path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/parameter");
-    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->bdf.domain,
-                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+    libxl__xs_printf(gc, XBT_NULL, path, PCI_BDF, pci->domain,
+                     pci->bus, pci->dev, pci->func);
 
     /* Remove all functions at once atomically by only signalling
      * device-model for function 0 */
@@ -1981,8 +1856,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
-        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->bdf.domain,
-                                     pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain,
+                                     pci->bus, pci->dev, pci->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
         int irq = 0;
@@ -2017,8 +1892,8 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs)
         }
         fclose(f);
 skip1:
-        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->bdf.domain,
-                               pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain,
+                               pci->bus, pci->dev, pci->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
@@ -2082,7 +1957,7 @@ static void pci_remove_qmp_device_del(libxl__egc *egc,
     if (rc) goto out;
 
     QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                           pci->bus, pci->dev, pci->func);
     prs->qmp.callback = pci_remove_qmp_device_del_cb;
     rc = libxl__ev_qmp_send(egc, &prs->qmp, "device_del", args);
     if (rc) goto out;
@@ -2151,7 +2026,7 @@ static void pci_remove_qmp_query_cb(libxl__egc *egc,
     libxl__ev_qmp_dispose(gc, qmp);
 
     asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                         pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+                         pci->bus, pci->dev, pci->func);
 
     /* query-pci response:
      * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
@@ -2202,7 +2077,7 @@ static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
     libxl_device_pci *const pci = &prs->pci;
 
     LOGD(WARN, prs->domid, "timed out waiting for DM to remove "
-         PCI_PT_QDEV_ID, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+         PCI_PT_QDEV_ID, pci->bus, pci->dev, pci->func);
 
     /* If we timed out, we might still want to keep destroying the device
      * (when force==true), so let the next function decide what to do on
@@ -2235,12 +2110,11 @@ static void pci_remove_detached(libxl__egc *egc,
 
     /* don't do multiple resets while some functions are still passed through */
     if ((pci->vdevfn & 0x7) == 0) {
-        libxl__device_pci_reset(gc, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func);
+        libxl__device_pci_reset(gc, pci->domain, pci->bus, pci->dev, pci->func);
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(CTX->xch, domid,
-                                pci_encode_bdf(&pci->bdf));
+        rc = xc_deassign_device(CTX->xch, domid, pci_encode_bdf(pci));
         if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
@@ -2315,23 +2189,6 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ev_time_init(&prs->timeout);
     libxl__ev_time_init(&prs->retry_timer);
 
-    if (pci->name) {
-        libxl_pci_bdf *pcibdf =
-            libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
-
-        if (!pcibdf) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
-             pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
-
-        libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf);
-        libxl_pci_bdf_dispose(pcibdf);
-        free(pcibdf);
-    }
-
     prs->orig_vdev = pci->vdevfn & ~7U;
 
     if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
@@ -2341,7 +2198,7 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
         }
         pci->vfunc_mask &= prs->pfunc_mask;
     } else {
-        prs->pfunc_mask = (1 << pci->bdf.func);
+        prs->pfunc_mask = (1 << pci->func);
     }
 
     rc = 0;
@@ -2369,7 +2226,7 @@ static void device_pci_remove_common_next(libxl__egc *egc,
         prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
             if ( pci->vfunc_mask == pfunc_mask ) {
-                pci->bdf.func = i;
+                pci->func = i;
                 pci->vdevfn = orig_vdev | i;
             } else {
                 pci->vdevfn = orig_vdev;
@@ -2386,7 +2243,7 @@ out:
     libxl__ev_time_deregister(gc, &prs->timeout);
     libxl__ev_time_deregister(gc, &prs->retry_timer);
 
-    if (!rc) pci_info_xs_remove(gc, &pci->bdf, "domid");
+    if (!rc) pci_info_xs_remove(gc, pci, "domid");
 
     libxl_device_pci_dispose(pci);
     aodev->rc = rc;
@@ -2466,10 +2323,6 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
         } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
     }
 
-    s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr));
-    if (s)
-        pci->name = strdup(s);
-
     return 0;
 }
 
@@ -2582,48 +2435,6 @@ DEFINE_DEVICE_TYPE_STRUCT(pci, PCI, pcidevs,
     .from_xenstore = libxl__device_pci_from_xs_be,
 );
 
-int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci,
-                                    int rebind)
-{
-    return libxl_pci_bdf_assignable_add(ctx, &pci->bdf, NULL, rebind);
-}
-
-int libxl_device_pci_assignable_remove(libxl_ctx *ctx, libxl_device_pci *pci,
-                                       int rebind)
-{
-    return libxl_pci_bdf_assignable_remove(ctx, &pci->bdf, rebind);
-}
-
-libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx,
-                                                   int *num)
-{
-    libxl_pci_bdf *pcibdfs = libxl_pci_bdf_assignable_list(ctx, num);
-    libxl_device_pci *pcis;
-    unsigned int i;
-
-    if (!pcibdfs)
-        return NULL;
-
-    pcis = calloc(*num, sizeof(*pcis));
-    if (!pcis) {
-        libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
-        return NULL;
-    }
-
-    for (i = 0; i < *num; i++) {
-        libxl_device_pci_init(&pcis[i]);
-        libxl_pci_bdf_copy(ctx, &pcis[i].bdf, &pcibdfs[i]);
-    }
-
-    libxl_pci_bdf_assignable_list_free(pcibdfs, *num);
-    return pcis;
-}
-
-void libxl_device_pci_assignable_list_free(libxl_device_pci *list, int num)
-{
-    libxl_device_pci_list_free(list, num);
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 32cc99beff..05324736b7 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -770,23 +770,18 @@ libxl_device_nic = Struct("device_nic", [
     ("colo_checkpoint_port", string)
     ])
 
-libxl_pci_bdf = Struct("pci_bdf", [
-    ("func", uint8),
-    ("dev", uint8),
-    ("bus", uint8),
-    ("domain", integer),
-    ])
-
 libxl_device_pci = Struct("device_pci", [
-    ("bdf", libxl_pci_bdf),
-    ("name", string),
-    ("vdevfn", uint32),
+    ("func",      uint8),
+    ("dev",       uint8),
+    ("bus",       uint8),
+    ("domain",    integer),
+    ("vdevfn",    uint32),
     ("vfunc_mask", uint32),
     ("msitranslate", bool),
     ("power_mgmt", bool),
     ("permissive", bool),
     ("seize", bool),
-    ("rdm_policy", libxl_rdm_reserve_policy),
+    ("rdm_policy",      libxl_rdm_reserve_policy),
     ])
 
 libxl_device_rdm = Struct("device_rdm", [
diff --git a/tools/libs/util/libxlu_pci.c b/tools/libs/util/libxlu_pci.c
index 543a1f80e9..1d38fffce3 100644
--- a/tools/libs/util/libxlu_pci.c
+++ b/tools/libs/util/libxlu_pci.c
@@ -1,7 +1,5 @@
 #define _GNU_SOURCE
 
-#include <ctype.h>
-
 #include "libxlu_internal.h"
 #include "libxlu_disk_l.h"
 #include "libxlu_disk_i.h"
@@ -11,218 +9,185 @@
 #define XLU__PCI_ERR(_c, _x, _a...) \
     if((_c) && (_c)->report) fprintf((_c)->report, _x, ##_a)
 
-static int parse_bdf(libxl_pci_bdf *bdfp, uint32_t *vfunc_maskp,
-                     const char *str, const char **endp)
+static int hex_convert(const char *str, unsigned int *val, unsigned int mask)
 {
-    const char *ptr = str;
-    unsigned int colons = 0;
-    unsigned int domain, bus, dev, func;
-    int n;
-
-    /* Count occurrences of ':' to detrmine presence/absence of the 'domain' */
-    while (isxdigit(*ptr) || *ptr == ':') {
-        if (*ptr == ':')
-            colons++;
-        ptr++;
-    }
-
-    ptr = str;
-    switch (colons) {
-    case 1:
-        domain = 0;
-        if (sscanf(ptr, "%x:%x.%n", &bus, &dev, &n) != 2)
-            return ERROR_INVAL;
-        break;
-    case 2:
-        if (sscanf(ptr, "%x:%x:%x.%n", &domain, &bus, &dev, &n) != 3)
-            return ERROR_INVAL;
-        break;
-    default:
-        return ERROR_INVAL;
-    }
-
-    if (domain > 0xffff || bus > 0xff || dev > 0x1f)
-        return ERROR_INVAL;
-
-    ptr += n;
-    if (*ptr == '*') {
-        if (!vfunc_maskp)
-            return ERROR_INVAL;
-        *vfunc_maskp = LIBXL_PCI_FUNC_ALL;
-        func = 0;
-        ptr++;
-    } else {
-        if (sscanf(ptr, "%x%n", &func, &n) != 1)
-            return ERROR_INVAL;
-        if (func > 7)
-            return ERROR_INVAL;
-        if (vfunc_maskp)
-            *vfunc_maskp = 1;
-        ptr += n;
-    }
-
-    bdfp->domain = domain;
-    bdfp->bus = bus;
-    bdfp->dev = dev;
-    bdfp->func = func;
-
-    if (endp)
-        *endp = ptr;
-
+    unsigned long ret;
+    char *end;
+
+    ret = strtoul(str, &end, 16);
+    if ( end == str || *end != '\0' )
+        return -1;
+    if ( ret & ~mask )
+        return -1;
+    *val = (unsigned int)ret & mask;
     return 0;
 }
 
-static int parse_vslot(uint32_t *vdevfnp, const char *str, const char **endp)
+static int pci_struct_fill(libxl_device_pci *pci, unsigned int domain,
+                           unsigned int bus, unsigned int dev,
+                           unsigned int func, unsigned int vdevfn)
 {
-    const char *ptr = str;
-    unsigned int val;
-    int n;
-
-    if (sscanf(ptr, "%x%n", &val, &n) != 1)
-        return ERROR_INVAL;
-
-    if (val > 0x1f)
-        return ERROR_INVAL;
-
-    ptr += n;
-
-    *vdevfnp = val << 3;
-
-    if (endp)
-        *endp = ptr;
-
+    pci->domain = domain;
+    pci->bus = bus;
+    pci->dev = dev;
+    pci->func = func;
+    pci->vdevfn = vdevfn;
     return 0;
 }
 
-static int parse_key_val(char **keyp, char**valp, const char *str,
-                         const char **endp)
+#define STATE_DOMAIN    0
+#define STATE_BUS       1
+#define STATE_DEV       2
+#define STATE_FUNC      3
+#define STATE_VSLOT     4
+#define STATE_OPTIONS_K 6
+#define STATE_OPTIONS_V 7
+#define STATE_TERMINAL  8
+#define STATE_TYPE      9
+#define STATE_RDM_STRATEGY      10
+#define STATE_RESERVE_POLICY    11
+#define INVALID         0xffffffff
+int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pci, const char *str)
 {
-    const char *ptr = str;
-    char *key, *val;
-
-    while (*ptr != '=' && *ptr != '\0')
-        ptr++;
+    unsigned state = STATE_DOMAIN;
+    unsigned dom = INVALID, bus = INVALID, dev = INVALID, func = INVALID, vslot = 0;
+    char *buf2, *tok, *ptr, *end, *optkey = NULL;
 
-    if (*ptr == '\0')
-        return ERROR_INVAL;
-
-    key = strndup(str, ptr - str);
-    if (!key)
-        return ERROR_NOMEM;
-
-    str = ++ptr; /* skip '=' */
-    while (*ptr != ',' && *ptr != '\0')
-        ptr++;
-
-    val = strndup(str, ptr - str);
-    if (!val) {
-        free(key);
+    if ( NULL == (buf2 = ptr = strdup(str)) )
         return ERROR_NOMEM;
-    }
-
-    if (*ptr == ',')
-        ptr++;
 
-    *keyp = key;
-    *valp = val;
-    *endp = ptr;
-
-    return 0;
-}
-
-static int parse_rdm_policy(XLU_Config *cfg, libxl_rdm_reserve_policy *policy,
-                            const char *str)
-{
-    int ret = libxl_rdm_reserve_policy_from_string(str, policy);
-
-    if (ret)
-        XLU__PCI_ERR(cfg, "Unknown RDM policy: %s", str);
-
-    return ret;
-}
-
-int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_pci_bdf *bdf, const char *str)
-{
-    return parse_bdf(bdf, NULL, str, NULL);
-}
-
-int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
-                              const char *str)
-{
-    const char *ptr = str;
-    bool bdf_present = false;
-    bool name_present = false;
-    int ret;
-
-    /* Attempt to parse 'bdf' as positional parameter */
-    ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, ptr, &ptr);
-    if (!ret) {
-        bdf_present = true;
-
-        /* Check whether 'vslot' if present */
-        if (*ptr == '@') {
-            ret = parse_vslot(&pcidev->vdevfn, ++ptr, &ptr);
-            if (ret)
-                return ret;
+    for(tok = ptr, end = ptr + strlen(ptr) + 1; ptr < end; ptr++) {
+        switch(state) {
+        case STATE_DOMAIN:
+            if ( *ptr == ':' ) {
+                state = STATE_BUS;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dom, 0xffff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_BUS:
+            if ( *ptr == ':' ) {
+                state = STATE_DEV;
+                *ptr = '\0';
+                if ( hex_convert(tok, &bus, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }else if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( dom & ~0xff )
+                    goto parse_error;
+                bus = dom;
+                dom = 0;
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_DEV:
+            if ( *ptr == '.' ) {
+                state = STATE_FUNC;
+                *ptr = '\0';
+                if ( hex_convert(tok, &dev, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_FUNC:
+            if ( *ptr == '\0' || *ptr == '@' || *ptr == ',' ) {
+                switch( *ptr ) {
+                case '\0':
+                    state = STATE_TERMINAL;
+                    break;
+                case '@':
+                    state = STATE_VSLOT;
+                    break;
+                case ',':
+                    state = STATE_OPTIONS_K;
+                    break;
+                }
+                *ptr = '\0';
+                if ( !strcmp(tok, "*") ) {
+                    pci->vfunc_mask = LIBXL_PCI_FUNC_ALL;
+                }else{
+                    if ( hex_convert(tok, &func, 0x7) )
+                        goto parse_error;
+                    pci->vfunc_mask = (1 << 0);
+                }
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_VSLOT:
+            if ( *ptr == '\0' || *ptr == ',' ) {
+                state = ( *ptr == ',' ) ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( hex_convert(tok, &vslot, 0xff) )
+                    goto parse_error;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_K:
+            if ( *ptr == '=' ) {
+                state = STATE_OPTIONS_V;
+                *ptr = '\0';
+                optkey = tok;
+                tok = ptr + 1;
+            }
+            break;
+        case STATE_OPTIONS_V:
+            if ( *ptr == ',' || *ptr == '\0' ) {
+                state = (*ptr == ',') ? STATE_OPTIONS_K : STATE_TERMINAL;
+                *ptr = '\0';
+                if ( !strcmp(optkey, "msitranslate") ) {
+                    pci->msitranslate = atoi(tok);
+                }else if ( !strcmp(optkey, "power_mgmt") ) {
+                    pci->power_mgmt = atoi(tok);
+                }else if ( !strcmp(optkey, "permissive") ) {
+                    pci->permissive = atoi(tok);
+                }else if ( !strcmp(optkey, "seize") ) {
+                    pci->seize = atoi(tok);
+                } else if (!strcmp(optkey, "rdm_policy")) {
+                    if (!strcmp(tok, "strict")) {
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                    } else if (!strcmp(tok, "relaxed")) {
+                        pci->rdm_policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                    } else {
+                        XLU__PCI_ERR(cfg, "%s is not an valid PCI RDM property"
+                                          " policy: 'strict' or 'relaxed'.",
+                                     tok);
+                        goto parse_error;
+                    }
+                } else {
+                    XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey);
+                }
+                tok = ptr + 1;
+            }
+        default:
+            break;
         }
-        if (*ptr == ',')
-            ptr++;
-        else if (*ptr != '\0')
-            return ERROR_INVAL;
     }
 
-    /* Parse the rest as 'key=val' pairs */
-    while (*ptr != '\0') {
-        char *key, *val;
-
-        ret = parse_key_val(&key, &val, ptr, &ptr);
-        if (ret)
-            return ret;
-
-        if (!strcmp(key, "bdf")) {
-            ret = parse_bdf(&pcidev->bdf, &pcidev->vfunc_mask, val, NULL);
-            bdf_present = !ret;
-        } else if (!strcmp(key, "vslot")) {
-            ret = parse_vslot(&pcidev->vdevfn, val, NULL);
-        } else if (!strcmp(key, "permissive")) {
-            pcidev->permissive = atoi(val);
-        } else if (!strcmp(key, "msitranslate")) {
-            pcidev->msitranslate = atoi(val);
-        } else if (!strcmp(key, "seize")) {
-            pcidev->seize= atoi(val);
-        } else if (!strcmp(key, "power_mgmt")) {
-            pcidev->power_mgmt = atoi(val);
-        } else if (!strcmp(key, "rdm_policy")) {
-            ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
-        } else if (!strcmp(key, "name")) {
-            name_present = true;
-            pcidev->name = strdup(val);
-            if (!pcidev->name) ret = ERROR_NOMEM;
-        } else {
-            XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
-            ret = ERROR_INVAL;
-        }
+    if ( tok != ptr || state != STATE_TERMINAL )
+        goto parse_error;
 
-        free(key);
-        free(val);
+    assert(dom != INVALID && bus != INVALID && dev != INVALID && func != INVALID);
 
-        if (ret)
-            return ret;
-    }
+    /* Just a pretty way to fill in the values */
+    pci_struct_fill(pci, dom, bus, dev, func, vslot << 3);
 
-    if (!(bdf_present ^ name_present))
-        return ERROR_INVAL;
+    free(buf2);
 
     return 0;
+
+parse_error:
+    free(buf2);
+    return ERROR_INVAL;
 }
 
 int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 {
-#define STATE_TYPE           0
-#define STATE_RDM_STRATEGY   1
-#define STATE_RESERVE_POLICY 2
-#define STATE_TERMINAL       3
-
     unsigned state = STATE_TYPE;
     char *buf2, *tok, *ptr, *end;
 
@@ -262,8 +227,15 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
             if (*ptr == ',' || *ptr == '\0') {
                 state = *ptr == ',' ? STATE_TYPE : STATE_TERMINAL;
                 *ptr = '\0';
-                if (!parse_rdm_policy(cfg, &rdm->policy, tok))
+                if (!strcmp(tok, "strict")) {
+                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_STRICT;
+                } else if (!strcmp(tok, "relaxed")) {
+                    rdm->policy = LIBXL_RDM_RESERVE_POLICY_RELAXED;
+                } else {
+                    XLU__PCI_ERR(cfg, "Unknown RDM property policy value: %s",
+                                 tok);
                     goto parse_error;
+                }
                 tok = ptr + 1;
             }
         default:
@@ -281,11 +253,6 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str)
 parse_error:
     free(buf2);
     return ERROR_INVAL;
-
-#undef STATE_TYPE
-#undef STATE_RDM_STRATEGY
-#undef STATE_RESERVE_POLICY
-#undef STATE_TERMINAL
 }
 
 /*
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index bd8af12ff3..6ab5e47da3 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -90,12 +90,12 @@ struct cmd_spec cmd_table[] = {
     { "pci-attach",
       &main_pciattach, 0, 1,
       "Insert a new pass-through pci device",
-      "<Domain> <PCI_SPEC_STRING>",
+      "<Domain> <BDF> [Virtual Slot]",
     },
     { "pci-detach",
       &main_pcidetach, 0, 1,
       "Remove a domain's pass-through pci device",
-      "<Domain> <PCI_SPEC_STRING>",
+      "<Domain> <BDF>",
     },
     { "pci-list",
       &main_pcilist, 0, 0,
@@ -105,25 +105,21 @@ struct cmd_spec cmd_table[] = {
     { "pci-assignable-add",
       &main_pciassignable_add, 0, 1,
       "Make a device assignable for pci-passthru",
-      "[options] <BDF>",
-      "-n NAME, --name=NAME    Name the assignable device.\n"
+      "<BDF>",
       "-h                      Print this help.\n"
     },
     { "pci-assignable-remove",
       &main_pciassignable_remove, 0, 1,
       "Remove a device from being assignable",
-      "[options] <BDF>|NAME",
+      "[options] <BDF>",
       "-h                      Print this help.\n"
       "-r                      Attempt to re-assign the device to the\n"
-      "                        original driver."
+      "                        original driver"
     },
     { "pci-assignable-list",
       &main_pciassignable_list, 0, 0,
       "List all the assignable pci devices",
-      "[options]",
-      "-h                      Print this help.\n"
-      "-n, --show-names        Display assignable device names where\n"
-      "                        supplied.\n"
+      "",
     },
     { "pause",
       &main_pause, 0, 1,
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 867e4d068a..4ebf39620a 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1487,10 +1487,10 @@ void parse_config_data(const char *config_source,
              * the global policy by default.
              */
             pci->rdm_policy = b_info->u.hvm.rdm.policy;
-            e = xlu_pci_parse_spec_string(config, pci, buf);
+            e = xlu_pci_parse_bdf(config, pci, buf);
             if (e) {
                 fprintf(stderr,
-                        "unable to parse PCI_SPEC_STRING `%s' for passthrough\n",
+                        "unable to parse PCI BDF `%s' for passthrough\n",
                         buf);
                 exit(-e);
             }
diff --git a/tools/xl/xl_pci.c b/tools/xl/xl_pci.c
index eb29b4e08d..f71498cbb5 100644
--- a/tools/xl/xl_pci.c
+++ b/tools/xl/xl_pci.c
@@ -34,8 +34,7 @@ static void pcilist(uint32_t domid)
     for (i = 0; i < num; i++) {
         printf("%02x.%01x %04x:%02x:%02x.%01x\n",
                (pcis[i].vdevfn >> 3) & 0x1f, pcis[i].vdevfn & 0x7,
-               pcis[i].bdf.domain, pcis[i].bdf.bus, pcis[i].bdf.dev,
-               pcis[i].bdf.func);
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
     }
     libxl_device_pci_list_free(pcis, num);
 }
@@ -55,7 +54,7 @@ int main_pcilist(int argc, char **argv)
     return 0;
 }
 
-static int pcidetach(uint32_t domid, const char *spec_string, int force)
+static int pcidetach(uint32_t domid, const char *bdf, int force)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -66,9 +65,8 @@ static int pcidetach(uint32_t domid, const char *spec_string, int force)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
-        fprintf(stderr, "pci-detach: malformed PCI_SPEC_STRING \"%s\"\n",
-                spec_string);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
     if (force) {
@@ -90,7 +88,7 @@ int main_pcidetach(int argc, char **argv)
     uint32_t domid;
     int opt;
     int force = 0;
-    const char *spec_string = NULL;
+    const char *bdf = NULL;
 
     SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
     case 'f':
@@ -99,15 +97,15 @@ int main_pcidetach(int argc, char **argv)
     }
 
     domid = find_domain(argv[optind]);
-    spec_string = argv[optind + 1];
+    bdf = argv[optind + 1];
 
-    if (pcidetach(domid, spec_string, force))
+    if (pcidetach(domid, bdf, force))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciattach(uint32_t domid, const char *spec_string)
+static int pciattach(uint32_t domid, const char *bdf, const char *vs)
 {
     libxl_device_pci pci;
     XLU_Config *config;
@@ -118,9 +116,8 @@ static int pciattach(uint32_t domid, const char *spec_string)
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_inig"); exit(-1); }
 
-    if (xlu_pci_parse_spec_string(config, &pci, spec_string)) {
-        fprintf(stderr, "pci-attach: malformed PCI_SPEC_STRING \"%s\"\n",
-                spec_string);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-attach: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
@@ -137,83 +134,72 @@ int main_pciattach(int argc, char **argv)
 {
     uint32_t domid;
     int opt;
-    const char *spec_string = NULL;
+    const char *bdf = NULL, *vs = NULL;
 
     SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
         /* No options */
     }
 
     domid = find_domain(argv[optind]);
-    spec_string = argv[optind + 1];
+    bdf = argv[optind + 1];
+
+    if (optind + 1 < argc)
+        vs = argv[optind + 2];
 
-    if (pciattach(domid, spec_string))
+    if (pciattach(domid, bdf, vs))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static void pciassignable_list(bool show_names)
+static void pciassignable_list(void)
 {
-    libxl_pci_bdf *pcibdfs;
+    libxl_device_pci *pcis;
     int num, i;
 
-    pcibdfs = libxl_pci_bdf_assignable_list(ctx, &num);
+    pcis = libxl_device_pci_assignable_list(ctx, &num);
 
-    if ( pcibdfs == NULL )
+    if ( pcis == NULL )
         return;
     for (i = 0; i < num; i++) {
-        libxl_pci_bdf *pcibdf = &pcibdfs[i];
-        char *name = show_names ?
-            libxl_pci_bdf_assignable_bdf2name(ctx, pcibdf) : NULL;
-
-        printf("%04x:%02x:%02x.%01x %s\n",
-               pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func,
-               name ?: "");
-
-        free(name);
+        printf("%04x:%02x:%02x.%01x\n",
+               pcis[i].domain, pcis[i].bus, pcis[i].dev, pcis[i].func);
     }
-    libxl_pci_bdf_assignable_list_free(pcibdfs, num);
+    libxl_device_pci_assignable_list_free(pcis, num);
 }
 
 int main_pciassignable_list(int argc, char **argv)
 {
     int opt;
-    static struct option opts[] = {
-        {"show-names", 0, 0, 'n'},
-        COMMON_LONG_OPTS
-    };
-    bool show_names = false;
-
-    SWITCH_FOREACH_OPT(opt, "n", opts, "pci-assignable-list", 0) {
-    case 'n':
-        show_names = true;
-        break;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
+        /* No options */
     }
 
-    pciassignable_list(show_names);
+    pciassignable_list();
     return 0;
 }
 
-static int pciassignable_add(const char *bdf, const char *name, int rebind)
+static int pciassignable_add(const char *bdf, int rebind)
 {
-    libxl_pci_bdf pcibdf;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
-    libxl_pci_bdf_init(&pcibdf);
+    libxl_device_pci_init(&pci);
 
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    if (xlu_pci_parse_bdf(config, &pcibdf, bdf)) {
-        fprintf(stderr, "pci-assignable-add: malformed BDF \"%s\"\n", bdf);
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf);
         exit(2);
     }
 
-    if (libxl_pci_bdf_assignable_add(ctx, &pcibdf, name, rebind))
+    if (libxl_device_pci_assignable_add(ctx, &pci, rebind))
         r = 1;
 
-    libxl_pci_bdf_dispose(&pcibdf);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -223,58 +209,39 @@ int main_pciassignable_add(int argc, char **argv)
 {
     int opt;
     const char *bdf = NULL;
-    static struct option opts[] = {
-        {"name", 1, 0, 'n'},
-        COMMON_LONG_OPTS
-    };
-    const char *name = NULL;
-
-    SWITCH_FOREACH_OPT(opt, "n:", opts, "pci-assignable-add", 0) {
-    case 'n':
-        name = optarg;
-        break;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
+        /* No options */
     }
 
     bdf = argv[optind];
 
-    if (pciassignable_add(bdf, name, 1))
+    if (pciassignable_add(bdf, 1))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
 }
 
-static int pciassignable_remove(const char *ident, int rebind)
+static int pciassignable_remove(const char *bdf, int rebind)
 {
-    libxl_pci_bdf *pcibdf;
+    libxl_device_pci pci;
     XLU_Config *config;
     int r = 0;
 
+    libxl_device_pci_init(&pci);
+
     config = xlu_cfg_init(stderr, "command line");
     if (!config) { perror("xlu_cfg_init"); exit(-1); }
 
-    pcibdf = libxl_pci_bdf_assignable_name2bdf(ctx, ident);
-    if (!pcibdf) {
-        pcibdf = calloc(1, sizeof(*pcibdf));
-
-        if (!pcibdf) {
-            fprintf(stderr,
-                    "pci-assignable-remove: failed to allocate memory\n");
-            exit(2);
-        }
-
-        libxl_pci_bdf_init(pcibdf);
-        if (xlu_pci_parse_bdf(config, pcibdf, ident)) {
-            fprintf(stderr,
-                    "pci-assignable-remove: malformed BDF '%s'\n", ident);
-            exit(2);
-        }
+    if (xlu_pci_parse_bdf(config, &pci, bdf)) {
+        fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf);
+        exit(2);
     }
 
-    if (libxl_pci_bdf_assignable_remove(ctx, pcibdf, rebind))
+    if (libxl_device_pci_assignable_remove(ctx, &pci, rebind))
         r = 1;
 
-    libxl_pci_bdf_dispose(pcibdf);
-    free(pcibdf);
+    libxl_device_pci_dispose(&pci);
     xlu_cfg_destroy(config);
 
     return r;
@@ -283,7 +250,7 @@ static int pciassignable_remove(const char *ident, int rebind)
 int main_pciassignable_remove(int argc, char **argv)
 {
     int opt;
-    const char *ident = NULL;
+    const char *bdf = NULL;
     int rebind = 0;
 
     SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
@@ -292,9 +259,9 @@ int main_pciassignable_remove(int argc, char **argv)
         break;
     }
 
-    ident = argv[optind];
+    bdf = argv[optind];
 
-    if (pciassignable_remove(ident, rebind))
+    if (pciassignable_remove(bdf, rebind))
         return EXIT_FAILURE;
 
     return EXIT_SUCCESS;
diff --git a/tools/xl/xl_sxp.c b/tools/xl/xl_sxp.c
index dc49fb7d50..359a001570 100644
--- a/tools/xl/xl_sxp.c
+++ b/tools/xl/xl_sxp.c
@@ -194,8 +194,8 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh)
         fprintf(fh, "\t(device\n");
         fprintf(fh, "\t\t(pci\n");
         fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
-               d_config->pcidevs[i].bdf.domain, d_config->pcidevs[i].bdf.bus,
-               d_config->pcidevs[i].bdf.dev, d_config->pcidevs[i].bdf.func,
+               d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
+               d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
                d_config->pcidevs[i].vdevfn);
         fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n",
                d_config->pcidevs[i].msitranslate,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56201.98214 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Fi-0000h5-IJ; Thu, 17 Dec 2020 23:00:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56201.98214; Thu, 17 Dec 2020 23:00:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Fi-0000gq-Da; Thu, 17 Dec 2020 23:00:06 +0000
Received: by outflank-mailman (input) for mailman id 56201;
 Thu, 17 Dec 2020 23:00:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fh-0000Vz-Aq
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fh-0001Qf-7G
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fh-0006mT-5K
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=D4Vgg7hznOyVJqOxvNesqBMXyjQiaUNgD6yR+pqRQPM=; b=CQF+ABuAYJyhBYS/wYC1yw0DWx
	qsuHQ0l/QQ+TQJgKUFm5HrFE41hRwlsxEYajrDshg2+shSVzbiHMoxERusKlR8+MU48f5wcuyZfo8
	4iPl6ysV7+Ad0q5ULPj3F+l9JYF6O6j/Qx+eQw7hMAeqffdx8BYjVNCB7SNAWikgp4Nc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add a QEMU aarch64 smoke test
Message-Id: <E1kq2Fh-0006mT-5K@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:05 +0000

commit dbc1e724bbcddf5de7a591ba7eb5a765a72de951
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Thu Nov 12 18:30:33 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add a QEMU aarch64 smoke test
    
    Use QEMU to start Xen (just the hypervisor) up until it stops because
    there is no dom0 kernel to boot.
    
    It is based on the existing build job unstable-arm64v8.
    
    Also use make -j$(nproc) to build Xen.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml         | 22 ++++++++++++++++++++++
 automation/scripts/build               |  6 +++---
 automation/scripts/qemu-smoke-arm64.sh | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index 793feafe8b..35346e3f6e 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -22,6 +22,28 @@ build-each-commit-gcc:
     - /^coverity-tested\/.*/
     - /^stable-.*/
 
+qemu-smoke-arm64-gcc:
+  stage: test
+  image: registry.gitlab.com/xen-project/xen/${CONTAINER}
+  variables:
+    CONTAINER: debian:unstable-arm64v8
+  script:
+    - ./automation/scripts/qemu-smoke-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
+  dependencies:
+    - debian-unstable-gcc-arm64
+  artifacts:
+    paths:
+      - smoke.serial
+      - '*.log'
+    when: always
+  tags:
+    - arm64
+  except:
+    - master
+    - smoke
+    - /^coverity-tested\/.*/
+    - /^stable-.*/
+
 qemu-smoke-x86-64-gcc:
   stage: test
   image: registry.gitlab.com/xen-project/xen/${CONTAINER}
diff --git a/automation/scripts/build b/automation/scripts/build
index 0cd0f3971d..7038e5eb50 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -10,9 +10,9 @@ cc-ver()
 
 # random config or default config
 if [[ "${RANDCONFIG}" == "y" ]]; then
-    make -C xen KCONFIG_ALLCONFIG=tools/kconfig/allrandom.config randconfig
+    make -j$(nproc) -C xen KCONFIG_ALLCONFIG=tools/kconfig/allrandom.config randconfig
 else
-    make -C xen defconfig
+    make -j$(nproc) -C xen defconfig
 fi
 
 # build up our configure options
@@ -45,7 +45,7 @@ make -j$(nproc) dist
 # Extract artifacts to avoid getting rewritten by customised builds
 cp xen/.config xen-config
 mkdir binaries
-if [[ "${XEN_TARGET_ARCH}" == "x86_64" ]]; then
+if [[ "${XEN_TARGET_ARCH}" != "x86_32" ]]; then
     cp xen/xen binaries/xen
 fi
 
diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
new file mode 100755
index 0000000000..1a0a98be6d
--- /dev/null
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -ex
+
+# Install QEMU
+export DEBIAN_FRONTENT=noninteractive
+apt-get -qy update
+apt-get -qy install --no-install-recommends qemu-system-aarch64 \
+                                            u-boot-qemu
+
+# XXX Silly workaround to get the following QEMU command to work
+# QEMU looks for "efi-virtio.rom" even if it is unneeded
+cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
+qemu-system-aarch64 \
+   -machine virtualization=true \
+   -cpu cortex-a57 -machine type=virt \
+   -m 512 -display none \
+   -machine dumpdtb=binaries/virt-gicv3.dtb
+
+rm -f smoke.serial
+set +e
+echo "  booti 0x49000000 - 0x44000000" | timeout -k 1 30 qemu-system-aarch64 \
+    -machine virtualization=true \
+    -cpu cortex-a57 -machine type=virt \
+    -m 512 -monitor none -serial stdio \
+    -no-reboot \
+    -device loader,file=binaries/virt-gicv3.dtb,force-raw=on,addr=0x44000000 \
+    -device loader,file=binaries/xen,force-raw=on,addr=0x49000000 \
+    -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
+
+set -e
+grep -q 'LOADING DOMAIN 0' smoke.serial || exit 1
+exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56202.98216 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Fs-0000p3-I7; Thu, 17 Dec 2020 23:00:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56202.98216; Thu, 17 Dec 2020 23:00:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Fs-0000ov-FB; Thu, 17 Dec 2020 23:00:16 +0000
Received: by outflank-mailman (input) for mailman id 56202;
 Thu, 17 Dec 2020 23:00:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fr-0000oq-DG
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fr-0001Qi-BF
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Fr-0006oA-9L
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ahTowqHvv53Fj4vQBWJs2szDGBvmU17u44mfSdU/GV0=; b=s5jCptSeCDwc5BHI1FP67xS6oZ
	cwmpGOkvpRrnSjuJZXM+W70yxrzszIUB1m4WOdxVbEboqr8O5keCCeHCSdSwyfitj8p+WMGmA/Tuy
	OWElWNs9lch3wcXaJwdrjVxJZ093jkoA6eUkp4QG/M4R1Q36gYZPYRoM9wnNj+/NP7Io=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add dom0less to the QEMU aarch64 smoke test
Message-Id: <E1kq2Fr-0006oA-9L@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:15 +0000

commit 8c5e5e85aa9908f2f3fbf110ef4341e5eba61657
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 13 15:22:41 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add dom0less to the QEMU aarch64 smoke test
    
    Add a trivial dom0less test:
    - fetch the Debian arm64 kernel and use it ad dom0/U kernel
    - use busybox-static to create a trivial dom0/U ramdisk
    - use ImageBuilder to generate the uboot boot script automatically
    - install and use u-boot from the Debian package to start the test
    - binaries are loaded from uboot via tftp
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/qemu-smoke-arm64.sh | 81 +++++++++++++++++++++++++++++++---
 1 file changed, 74 insertions(+), 7 deletions(-)

diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
index 1a0a98be6d..794c53f887 100755
--- a/automation/scripts/qemu-smoke-arm64.sh
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -6,7 +6,17 @@ set -ex
 export DEBIAN_FRONTENT=noninteractive
 apt-get -qy update
 apt-get -qy install --no-install-recommends qemu-system-aarch64 \
-                                            u-boot-qemu
+                                            u-boot-qemu \
+                                            u-boot-tools \
+                                            device-tree-compiler \
+                                            busybox-static \
+                                            cpio
+
+cd binaries
+apt-get download linux-image-*[0-9]-arm64
+dpkg -i --ignore-depends=initramfs-tools ./linux-image-*arm64.deb || true
+cp /boot/vmlinuz-*arm64 ./Image
+cd ..
 
 # XXX Silly workaround to get the following QEMU command to work
 # QEMU looks for "efi-virtio.rom" even if it is unneeded
@@ -14,20 +24,77 @@ cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
 qemu-system-aarch64 \
    -machine virtualization=true \
    -cpu cortex-a57 -machine type=virt \
-   -m 512 -display none \
+   -m 1024 -display none \
    -machine dumpdtb=binaries/virt-gicv3.dtb
+# XXX disable pl061 to avoid Linux crash
+dtc -I dtb -O dts binaries/virt-gicv3.dtb > binaries/virt-gicv3.dts
+sed 's/compatible = "arm,pl061.*/status = "disabled";/g' binaries/virt-gicv3.dts > binaries/virt-gicv3-edited.dts
+dtc -I dts -O dtb binaries/virt-gicv3-edited.dts > binaries/virt-gicv3.dtb
+
+
+# Busybox Dom0
+mkdir -p initrd
+mkdir -p initrd/bin
+mkdir -p initrd/sbin
+mkdir -p initrd/etc
+mkdir -p initrd/dev
+mkdir -p initrd/proc
+mkdir -p initrd/sys
+mkdir -p initrd/lib
+mkdir -p initrd/var
+mkdir -p initrd/mnt
+cp /bin/busybox initrd/bin/busybox
+initrd/bin/busybox --install initrd/bin
+echo "#!/bin/sh
+
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devtmpfs devtmpfs /dev
+/bin/sh" > initrd/init
+chmod +x initrd/init
+cd initrd
+find . | cpio --create --format='newc' | gzip > ../binaries/initrd
+cd ..
+
+
+# ImageBuilder
+echo 'MEMORY_START="0x40000000"
+MEMORY_END="0x80000000"
 
+DEVICE_TREE="virt-gicv3.dtb"
+XEN="xen"
+DOM0_KERNEL="Image"
+DOM0_RAMDISK="initrd"
+XEN_CMD="console=dtuart dom0_mem=512M"
+
+NUM_DOMUS=1
+DOMU_KERNEL[0]="Image"
+DOMU_RAMDISK[0]="initrd"
+DOMU_MEM[0]="256"
+
+LOAD_CMD="tftpb"
+UBOOT_SOURCE="boot.source"
+UBOOT_SCRIPT="boot.scr"' > binaries/config
+rm -rf imagebuilder
+git clone https://gitlab.com/ViryaOS/imagebuilder
+bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/config
+
+
+# Run the test
 rm -f smoke.serial
 set +e
-echo "  booti 0x49000000 - 0x44000000" | timeout -k 1 30 qemu-system-aarch64 \
+echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
+timeout -k 1 240 \
+qemu-system-aarch64 \
     -machine virtualization=true \
     -cpu cortex-a57 -machine type=virt \
-    -m 512 -monitor none -serial stdio \
+    -m 1024 -monitor none -serial stdio \
+    -smp 2 \
     -no-reboot \
-    -device loader,file=binaries/virt-gicv3.dtb,force-raw=on,addr=0x44000000 \
-    -device loader,file=binaries/xen,force-raw=on,addr=0x49000000 \
+    -device virtio-net-pci,netdev=n0 \
+    -netdev user,id=n0,tftp=binaries \
     -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
 
 set -e
-grep -q 'LOADING DOMAIN 0' smoke.serial || exit 1
+(grep -q "^BusyBox" smoke.serial && grep -q "DOM1: BusyBox" smoke.serial) || exit 1
 exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56204.98224 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2G2-0000r8-LB; Thu, 17 Dec 2020 23:00:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56204.98224; Thu, 17 Dec 2020 23:00:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2G2-0000r0-Hz; Thu, 17 Dec 2020 23:00:26 +0000
Received: by outflank-mailman (input) for mailman id 56204;
 Thu, 17 Dec 2020 23:00:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2G1-0000qp-Ff
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2G1-0001Qr-Es
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2G1-0006on-DC
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6fsGEv8Z39CLDs40DaHN5WHdMjnISCjbjp2uf5IPo6o=; b=xFCmMGe7m4ysryKzzB81cxLg5u
	C7WSjmoTLgadBCKWTx/2qOatFu4kud2HzttMUgGu3bEXXtBxnVF7EiHQgD1pcTNGq4tYl1e3QGEHS
	sKi91iWjvSrho8ZwEytJ6EruiWOYi+j4jYPoIOXAgUVTfSpD+gN0kNG2ioEi1+660oO8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: special configure flags for musl-based systems
Message-Id: <E1kq2G1-0006on-DC@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:25 +0000

commit 3a51115ab50fd2561b94cb6ec0a597db81549240
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Thu Nov 19 19:20:15 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: special configure flags for musl-based systems
    
    QEMU upstream builds with warnings when libc is musl:
    
      #warning redirecting incorrect #include <sys/signal.h> to <signal.h>
    
    Disable -Werror by passing --disable-werror to the QEMUU config script
    if libc is musl.
    
    hvmloader doesn't build on musl systems today. Disable any guest
    firmware build.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/build | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/automation/scripts/build b/automation/scripts/build
index 7038e5eb50..959a26d084 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -28,6 +28,14 @@ if [[ "${CC}" == "clang"* ]]; then
     cfgargs+=("--disable-stubdom")
 fi
 
+if ! test -z "$(ldd /bin/ls|grep musl|head -1)"; then
+    # disable --disable-werror for QEMUU when building with MUSL
+    cfgargs+=("--with-extra-qemuu-configure-args=\"--disable-werror\"")
+    # hvmloader doesn't build on MUSL systems
+    cfgargs+=("--disable-seabios")
+    cfgargs+=("--disable-rombios")
+fi
+
 # Qemu requires Python 3.5 or later
 if ! type python3 || python3 -c "import sys; res = sys.version_info < (3, 5); exit(not(res))"; then
     cfgargs+=("--with-system-qemu=/bin/false")
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56205.98228 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GC-0000sa-Ms; Thu, 17 Dec 2020 23:00:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56205.98228; Thu, 17 Dec 2020 23:00:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GC-0000sR-JT; Thu, 17 Dec 2020 23:00:36 +0000
Received: by outflank-mailman (input) for mailman id 56205;
 Thu, 17 Dec 2020 23:00:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GB-0000sH-JK
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GB-0001R6-IW
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GB-0006pa-Gr
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=w1N52ag6hYhGX2yUgmkwxqg/CWT55l+r0aX4DpZUYWY=; b=1c6JT7vkM3ibQdoaFS23raxNE5
	l0cciW9SWOO670xwyL+Hc3Pu6SdHXo7CsQQ84ifvKjmuLeQZGJJGhELC/pDB0+J3tOiEzaYFmbfaP
	rpk2YUUqHB1dZ9WdrXfyrNmkIfQNSpo4VjqQnUPxKHWbTugg8ac1FTxVKOWKuUgm9dhY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add alpine linux 3.12 arm64 build container
Message-Id: <E1kq2GB-0006pa-Gr@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:35 +0000

commit 335ddd8ff62e67b02ad794cadb671f843159a29c
Author:     Stefano Stabellini <stefano.stabellini@xilinx.com>
AuthorDate: Tue Nov 17 17:03:55 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux 3.12 arm64 build container
    
    The build container will be used for a new Alpine Linux 3.12 arm64 build
    test.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/build/alpine/3.12-arm64v8.dockerfile | 52 +++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/automation/build/alpine/3.12-arm64v8.dockerfile b/automation/build/alpine/3.12-arm64v8.dockerfile
new file mode 100644
index 0000000000..d6cdf5b200
--- /dev/null
+++ b/automation/build/alpine/3.12-arm64v8.dockerfile
@@ -0,0 +1,52 @@
+FROM arm64v8/alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen build deps
+  apk add argp-standalone && \
+  apk add autoconf && \
+  apk add automake && \
+  apk add bash && \
+  apk add curl && \
+  apk add curl-dev && \
+  apk add dev86 && \
+  apk add dtc-dev && \
+  apk add gcc  && \
+  apk add gettext && \
+  apk add git && \
+  apk add iasl && \
+  apk add libaio-dev && \
+  apk add libfdt && \
+  apk add linux-headers && \
+  apk add make && \
+  apk add musl-dev  && \
+  apk add ncurses-dev && \
+  apk add patch  && \
+  apk add python3-dev && \
+  apk add texinfo && \
+  apk add util-linux-dev && \
+  apk add xz-dev && \
+  apk add yajl-dev && \
+  apk add zlib-dev && \
+  \
+  # qemu build deps
+  apk add bison && \
+  apk add flex && \
+  apk add glib-dev && \
+  apk add libattr && \
+  apk add libcap-ng-dev && \
+  apk add pixman-dev && \
+  \
+  # cleanup
+  rm -rf /tmp/* && \
+  rm -f /var/cache/apk/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56206.98231 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GN-0000uD-Nw; Thu, 17 Dec 2020 23:00:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56206.98231; Thu, 17 Dec 2020 23:00:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GN-0000u7-Ky; Thu, 17 Dec 2020 23:00:47 +0000
Received: by outflank-mailman (input) for mailman id 56206;
 Thu, 17 Dec 2020 23:00:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GL-0000tx-MI
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GL-0001RE-LS
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GL-0006qY-KW
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=D8/9tcfYja57p0ydK0ae+jQb1hpFNeB1RlZ+phUf/LY=; b=fV8jnM+gO4oONvfOVxdi8gUlts
	odpNeAW2UALLXQQy2hc3aEfBRsMVG19GzABdVlQZvwhJSo7Ndh5Jv/L2VUgX1N8/K3Wempax7urOF
	877UT/xZcFGCKsKt4FjYBP1dtylvx/yPJ2xWXU3fmdejwNUC9syzz8DFpR8ighzPJ3OE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add alpine linux arm64 build test
Message-Id: <E1kq2GL-0006qY-KW@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:45 +0000

commit c5f8e7d613b8e68b61e6895bd5914e4868aa3013
Author:     Stefano Stabellini <stefano.stabellini@xilinx.com>
AuthorDate: Tue Nov 17 17:07:43 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux arm64 build test
    
    Based on the arm64 3.12 build container
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index 4bd1cfc1c0..fa38c39d6a 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -434,3 +434,12 @@ debian-unstable-gcc-debug-arm64-randconfig:
     CONTAINER: debian:unstable-arm64v8
     RANDCONFIG: y
 
+alpine-3.12-gcc-arm64:
+  extends: .gcc-arm64-build
+  variables:
+    CONTAINER: alpine:3.12-arm64v8
+
+alpine-3.12-gcc-debug-arm64:
+  extends: .gcc-arm64-build-debug
+  variables:
+    CONTAINER: alpine:3.12-arm64v8
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:00:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:00:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56207.98235 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GX-0000vW-PJ; Thu, 17 Dec 2020 23:00:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56207.98235; Thu, 17 Dec 2020 23:00:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2GX-0000vO-MR; Thu, 17 Dec 2020 23:00:57 +0000
Received: by outflank-mailman (input) for mailman id 56207;
 Thu, 17 Dec 2020 23:00:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GV-0000vA-Ph
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GV-0001RQ-Ow
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2GV-0006rC-NT
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:00:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=VRzLBYCHJmsCE4FeI0mcfdHByIVNPIPnAV5X1ju2c94=; b=BOFb3c9qornSSFbmZMamQGbxhy
	IFXwiOmPSnaDMSEkPmZJZ5PqJOvv6DiS51wvh9HyRSjFoCiSMz0ivCshNDJgxahDG4qRRGNYyVRnY
	cNwSLb7Se//Aj62UjfD1yaYU68NiXsqJdE64SSdBiDBAqrBJHjOGzGOD7k/IaaQajgl0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add alpine linux 3.12 x86 build container
Message-Id: <E1kq2GV-0006rC-NT@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:00:55 +0000

commit a9afe7768bdae3e22aec5fe67360e46f8f3e3cea
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 20 09:54:01 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux 3.12 x86 build container
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/build/alpine/3.12.dockerfile | 52 +++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/automation/build/alpine/3.12.dockerfile b/automation/build/alpine/3.12.dockerfile
new file mode 100644
index 0000000000..2c02417ee6
--- /dev/null
+++ b/automation/build/alpine/3.12.dockerfile
@@ -0,0 +1,52 @@
+FROM alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen build deps
+  apk add argp-standalone && \
+  apk add autoconf && \
+  apk add automake && \
+  apk add bash && \
+  apk add curl && \
+  apk add curl-dev && \
+  apk add dev86 && \
+  apk add gcc  && \
+  apk add clang  && \
+  apk add gettext && \
+  apk add git && \
+  apk add iasl && \
+  apk add libaio-dev && \
+  apk add linux-headers && \
+  apk add make && \
+  apk add musl-dev  && \
+  apk add libc6-compat && \
+  apk add ncurses-dev && \
+  apk add patch  && \
+  apk add python3-dev && \
+  apk add texinfo && \
+  apk add util-linux-dev && \
+  apk add xz-dev && \
+  apk add yajl-dev && \
+  apk add zlib-dev && \
+  \
+  # qemu build deps
+  apk add bison && \
+  apk add flex && \
+  apk add glib-dev && \
+  apk add libattr && \
+  apk add libcap-ng-dev && \
+  apk add pixman-dev && \
+  \
+  # cleanup
+  rm -rf /tmp/* && \
+  rm -f /var/cache/apk/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56208.98239 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Gh-0000wz-RA; Thu, 17 Dec 2020 23:01:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56208.98239; Thu, 17 Dec 2020 23:01:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Gh-0000ws-Nw; Thu, 17 Dec 2020 23:01:07 +0000
Received: by outflank-mailman (input) for mailman id 56208;
 Thu, 17 Dec 2020 23:01:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gf-0000wh-TF
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gf-0001TY-SF
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gf-0006s7-Qu
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=suQyeKaxg9Wsx06mkHmKzhOdg3hjwg0Uk1vN0Mqk4KI=; b=IpsfuR2Hxgs+8mixtqPRQOGVnN
	JN0Hvbi0CG1CHqDYEBUDEPKTTDYVSNPYlC07k7auknr0qBF7BkH5naUPWctFDl25bxRYAFhQK36qo
	cg8ltlYjWMGF+Iy0o13YGepK2DX2rpwqdKetkvMq/ZbgqvHF7UwHOpJWcxHltwrWIlJo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add alpine linux x86 build jobs
Message-Id: <E1kq2Gf-0006s7-Qu@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:05 +0000

commit f6e1d8515d7d69fda131e469576a555f66fde66c
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 20 09:56:25 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux x86 build jobs
    
    Allow failure for these jobs. Currently they fail because hvmloader
    doesn't build with musl. The failures don't block the pipeline.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index fa38c39d6a..c48c0f3d66 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -410,6 +410,31 @@ opensuse-leap-gcc-debug:
   variables:
     CONTAINER: suse:opensuse-leap
 
+alpine-3.12-gcc:
+  extends: .gcc-x86-64-build
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-gcc-debug:
+  extends: .gcc-x86-64-build-debug
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-clang:
+  extends: .gcc-x86-64-build
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-clang-debug:
+  extends: .gcc-x86-64-build-debug
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+
 # Arm builds
 
 debian-unstable-gcc-arm64:
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56209.98243 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Gr-0000ya-U8; Thu, 17 Dec 2020 23:01:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56209.98243; Thu, 17 Dec 2020 23:01:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2Gr-0000yS-RE; Thu, 17 Dec 2020 23:01:17 +0000
Received: by outflank-mailman (input) for mailman id 56209;
 Thu, 17 Dec 2020 23:01:16 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gq-0000y9-0E
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:16 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gp-0001Tg-Vg
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2Gp-0006t4-UJ
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=iTuBL9wcxRywDyBzCCUln2A+oqZnGEFuuSEXGTsy4HI=; b=PKL9AWkzYoS/IGuYaefmfOMSNI
	/mmwi9Ytra/g0M6Ezru3zGhtgkqrd1E1n1iepfGRQQRnH+EahtACkYNwIPKcHZbkYOXLV/wVCXas8
	wJ5NzAxkQDWsm9pFZRf58MusmXjbFZBNSZMtFmf9bo5eepzTVDBAA74R778Qk3HBPPNM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add tests artifacts
Message-Id: <E1kq2Gp-0006t4-UJ@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:15 +0000

commit e1681ce44cab50317fba33774b93c56c18fcae64
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:08:20 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add tests artifacts
    
    Some tests (soon to come) will require pre-built binaries to run, such
    as the Linux kernel binary. We don't want to rebuild the Linux kernel
    for each gitlab-ci run: these builds should not be added to the current
    list of build jobs.
    
    Instead, create additional containers that today are built and uploaded
    manually, but could be re-built automatically. The containers build the
    required binarires during the "docker build" step and store them inside
    the container itself.
    
    gitlab-ci will be able to fetch these pre-built binaries during the
    regular test runs, saving cycles.
    
    Add two tests artifacts containers:
    - one to build the Linux kernel ARM64
    - one to create an Alpine Linux ARM64 rootfs for Dom0
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/tests-artifacts/Makefile                | 19 ++++++
 .../tests-artifacts/alpine/3.12-arm64v8.dockerfile | 67 ++++++++++++++++++++++
 .../kernel/5.9.9-arm64v8.dockerfile                | 34 +++++++++++
 3 files changed, 120 insertions(+)

diff --git a/automation/tests-artifacts/Makefile b/automation/tests-artifacts/Makefile
new file mode 100644
index 0000000000..8ca71b78ad
--- /dev/null
+++ b/automation/tests-artifacts/Makefile
@@ -0,0 +1,19 @@
+
+# the base of where these containers will appear
+REGISTRY := registry.gitlab.com/xen-project/xen/tests-artifacts
+CONTAINERS = $(subst .dockerfile,,$(wildcard */*.dockerfile))
+
+help:
+	@echo "Containers to build and export tests artifacts."
+	@echo "To build one run 'make ARTIFACT/VERSION'. Available containers:"
+	@$(foreach file,$(sort $(CONTAINERS)),echo ${file};)
+	@echo "To push container builds, set the env var PUSH"
+
+%: %.dockerfile ## Builds containers
+	docker build -t $(REGISTRY)/$(@D):$(@F) -f $< $(<D)
+	@if [ ! -z $${PUSH+x} ]; then \
+		docker push $(REGISTRY)/$(@D):$(@F); \
+	fi
+
+.PHONY: all
+all: $(CONTAINERS)
diff --git a/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile b/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile
new file mode 100644
index 0000000000..9457009452
--- /dev/null
+++ b/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile
@@ -0,0 +1,67 @@
+FROM arm64v8/alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen runtime deps
+  apk add musl && \
+  apk add openrc && \
+  apk add busybox && \
+  apk add sudo && \
+  apk add dbus && \
+  apk add bash && \
+  apk add python2 && \
+  apk add gettext && \
+  apk add zlib && \
+  apk add ncurses && \
+  apk add texinfo && \
+  apk add yajl && \
+  apk add libaio && \
+  apk add xz-dev && \
+  apk add util-linux && \
+  apk add argp-standalone && \
+  apk add libfdt && \
+  apk add glib && \
+  apk add pixman && \
+  apk add curl && \
+  apk add udev && \
+  \
+  # Xen
+  cd / && \
+  # Minimal ramdisk environment in case of cpio output
+  rc-update add udev && \
+  rc-update add udev-trigger && \
+  rc-update add udev-settle && \
+  rc-update add networking sysinit && \
+  rc-update add loopback sysinit && \
+  rc-update add bootmisc boot && \
+  rc-update add devfs sysinit && \
+  rc-update add dmesg sysinit && \
+  rc-update add hostname boot && \
+  rc-update add hwclock boot && \
+  rc-update add hwdrivers sysinit && \
+  rc-update add killprocs shutdown && \
+  rc-update add modloop sysinit && \
+  rc-update add modules boot && \
+  rc-update add mount-ro shutdown && \
+  rc-update add savecache shutdown && \
+  rc-update add sysctl boot && \
+  rc-update add local default && \
+  cp -a /sbin/init /init && \
+  echo "ttyS0" >> /etc/securetty && \
+  echo "hvc0" >> /etc/securetty && \
+  echo "ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100" >> /etc/inittab && \
+  echo "hvc0::respawn:/sbin/getty -L hvc0 115200 vt100" >> /etc/inittab && \
+  passwd -d "root" root && \
+  \
+  # Create rootfs
+  cd / && \
+  tar cvzf /initrd.tar.gz bin dev etc home init lib mnt opt root sbin usr var
diff --git a/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile b/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile
new file mode 100644
index 0000000000..053d65a345
--- /dev/null
+++ b/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile
@@ -0,0 +1,34 @@
+FROM arm64v8/debian:unstable
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV DEBIAN_FRONTEND=noninteractive
+ENV LINUX_VERSION=5.9.9
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN apt-get update && \
+    apt-get --quiet --yes install \
+        build-essential \
+        libssl-dev \
+        bc \
+        curl \
+        flex \
+        bison \
+        && \
+    \
+    # Build the kernel
+    curl -fsSLO https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-"$LINUX_VERSION".tar.xz && \
+    tar xvJf linux-"$LINUX_VERSION".tar.xz && \
+    cd linux-"$LINUX_VERSION" && \
+    make defconfig && \
+    make -j$(nproc) Image.gz && \
+    cp arch/arm64/boot/Image / && \
+    cd /build && \
+    rm -rf linux-"$LINUX_VERSION"* && \
+    apt-get autoremove -y && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists* /tmp/* /var/tmp/*
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:28 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56210.98246 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2H1-0000zk-Va; Thu, 17 Dec 2020 23:01:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56210.98246; Thu, 17 Dec 2020 23:01:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2H1-0000zc-Sj; Thu, 17 Dec 2020 23:01:27 +0000
Received: by outflank-mailman (input) for mailman id 56210;
 Thu, 17 Dec 2020 23:01:26 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2H0-0000zS-2q
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:26 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2H0-0001Tp-27
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:26 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2H0-0006tz-1R
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:26 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tTcL1g2/ki0zdtCSFxT2gnBlwgfIMVAF+Svq9Yk2F1Q=; b=20QR6hEh5NRW+ZrthZmaFDwqUS
	E7tVOqK/XD30+VwGekMFYVmP1Of9e4eeoCEP4SZowsFlU8zEC0jX4PG7gXsfVVZFVrAxirRbwDNeu
	icXHYGYcouUhLOpOuvVafTzXx+cuIgzQnPeeH+8/alxBdV55oQmXdXbb6d2L33h47H7Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: make available the tests artifacts to the pipeline
Message-Id: <E1kq2H0-0006tz-1R@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:26 +0000

commit 7b532ee54ecc297cd41aaaffd79436ecbfe4188e
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:13:50 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: make available the tests artifacts to the pipeline
    
    In order to make available the pre-built binaries of the
    automation/tests-artifacts containers to the gitlab-ci pipeline we need
    to export them as gitlab artifacts.
    
    To do that, we create two "fake" jobs that simply export the require
    binaries as artifacts and do nothing else.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index c48c0f3d66..e5246828f8 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -468,3 +468,29 @@ alpine-3.12-gcc-debug-arm64:
   extends: .gcc-arm64-build-debug
   variables:
     CONTAINER: alpine:3.12-arm64v8
+
+
+# Arm test artifacts
+
+alpine-3.12-arm64-rootfs-export:
+  stage: build
+  image: registry.gitlab.com/xen-project/xen/tests-artifacts/alpine:3.12-arm64v8
+  script:
+    - mkdir binaries && cp /initrd.tar.gz binaries/initrd.tar.gz
+  artifacts:
+    paths:
+      - binaries/initrd.tar.gz
+  tags:
+    - arm64
+
+kernel-5.9.9-arm64-export:
+  stage: build
+  image: registry.gitlab.com/xen-project/xen/tests-artifacts/kernel:5.9.9-arm64v8
+  script:
+    - mkdir binaries && cp /Image binaries/Image
+  artifacts:
+    paths:
+      - binaries/Image
+  tags:
+    - arm64
+
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:37 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:37 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56211.98252 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HB-000116-1c; Thu, 17 Dec 2020 23:01:37 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56211.98252; Thu, 17 Dec 2020 23:01:37 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HA-00010w-UH; Thu, 17 Dec 2020 23:01:36 +0000
Received: by outflank-mailman (input) for mailman id 56211;
 Thu, 17 Dec 2020 23:01:36 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HA-00010o-66
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:36 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HA-0001Tz-5N
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:36 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HA-0006uo-4C
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:36 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FsNurEK38WupGmhbJqHUAcJ2r3PiaIVDtI1OZSnE5aM=; b=PcqJ8oHNoqRikNTN1cYEzQZLv5
	MewUbUjDMT0Y5cLTp1FGJik/mLbAszn2Kr+GmYn02lcgnkEmMQq0wo1/CYAr9LPe4IBh/iDpH3cbt
	RsMbbtVqp9gWqgxNAk+SkeZWr4aP1lTlFjlM8RY4sp5bF+xw8bwi+5+esaM4uImMXJcU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: create an alpine linux arm64 test job
Message-Id: <E1kq2HA-0006uo-4C@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:36 +0000

commit b44eb6daa96b1f3eae21b4fd5c1307519c71275a
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:15:51 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: create an alpine linux arm64 test job
    
    Create a test job that starts Xen and Dom0 on QEMU based on the alpine
    linux rootfs. Use the Linux kernel and rootfs from the tests-artifacts
    containers. Add the Xen tools binaries from the Alpine Linux build job.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml          | 24 ++++++++++
 automation/scripts/build                |  1 +
 automation/scripts/qemu-alpine-arm64.sh | 85 +++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index 35346e3f6e..a291538d68 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -22,6 +22,30 @@ build-each-commit-gcc:
     - /^coverity-tested\/.*/
     - /^stable-.*/
 
+qemu-alpine-arm64-gcc:
+  stage: test
+  image: registry.gitlab.com/xen-project/xen/${CONTAINER}
+  variables:
+    CONTAINER: debian:unstable-arm64v8
+  script:
+    - ./automation/scripts/qemu-alpine-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
+  dependencies:
+    - alpine-3.12-gcc-arm64
+    - alpine-3.12-arm64-rootfs-export
+    - kernel-5.9.9-arm64-export
+  artifacts:
+    paths:
+      - smoke.serial
+      - '*.log'
+    when: always
+  tags:
+    - arm64
+  except:
+    - master
+    - smoke
+    - /^coverity-tested\/.*/
+    - /^stable-.*/
+
 qemu-smoke-arm64-gcc:
   stage: test
   image: registry.gitlab.com/xen-project/xen/${CONTAINER}
diff --git a/automation/scripts/build b/automation/scripts/build
index 959a26d084..d8990c3bf4 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -55,6 +55,7 @@ cp xen/.config xen-config
 mkdir binaries
 if [[ "${XEN_TARGET_ARCH}" != "x86_32" ]]; then
     cp xen/xen binaries/xen
+    cp -r dist binaries/
 fi
 
 # Build all the configs we care about
diff --git a/automation/scripts/qemu-alpine-arm64.sh b/automation/scripts/qemu-alpine-arm64.sh
new file mode 100755
index 0000000000..62aae2d4c8
--- /dev/null
+++ b/automation/scripts/qemu-alpine-arm64.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+set -ex
+
+apt-get -qy update
+apt-get -qy install --no-install-recommends qemu-system-aarch64 \
+                                            u-boot-qemu \
+                                            u-boot-tools \
+                                            device-tree-compiler \
+                                            cpio \
+                                            curl
+
+mkdir -p binaries/rootfs
+cd binaries/rootfs
+tar xvzf ../initrd.tar.gz
+mkdir proc
+mkdir run
+mkdir srv
+mkdir sys
+rm var/run
+cp -ar ../dist/install/* .
+echo "#!/bin/bash
+
+export LD_LIBRARY_PATH=/usr/local/lib
+bash /etc/init.d/xencommons start
+
+xl list
+
+" > etc/local.d/xen.start
+chmod +x etc/local.d/xen.start
+echo "rc_verbose=yes" >> etc/rc.conf
+find . |cpio -H newc -o|gzip > ../xen-rootfs.cpio.gz
+cd ../..
+
+# XXX Silly workaround to get the following QEMU command to work
+# QEMU looks for "efi-virtio.rom" even if it is unneeded
+cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
+qemu-system-aarch64 \
+   -machine virtualization=true \
+   -cpu cortex-a57 -machine type=virt \
+   -m 1024 -display none \
+   -machine dumpdtb=binaries/virt-gicv3.dtb
+# XXX disable pl061 to avoid Linux crash
+dtc -I dtb -O dts binaries/virt-gicv3.dtb > binaries/virt-gicv3.dts
+sed 's/compatible = "arm,pl061.*/status = "disabled";/g' binaries/virt-gicv3.dts > binaries/virt-gicv3-edited.dts
+dtc -I dts -O dtb binaries/virt-gicv3-edited.dts > binaries/virt-gicv3.dtb
+
+# ImageBuilder
+echo 'MEMORY_START="0x40000000"
+MEMORY_END="0x80000000"
+
+DEVICE_TREE="virt-gicv3.dtb"
+XEN="xen"
+DOM0_KERNEL="Image"
+DOM0_RAMDISK="xen-rootfs.cpio.gz"
+XEN_CMD="console=dtuart dom0_mem=1024M"
+
+NUM_DOMUS=0
+
+LOAD_CMD="tftpb"
+UBOOT_SOURCE="boot.source"
+UBOOT_SCRIPT="boot.scr"' > binaries/config
+rm -rf imagebuilder
+git clone https://gitlab.com/ViryaOS/imagebuilder
+bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/config
+
+
+# Run the test
+rm -f smoke.serial
+set +e
+echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
+timeout -k 1 480 \
+qemu-system-aarch64 \
+    -machine virtualization=true \
+    -cpu cortex-a57 -machine type=virt \
+    -m 2048 -monitor none -serial stdio \
+    -smp 2 \
+    -no-reboot \
+    -device virtio-net-pci,netdev=n0 \
+    -netdev user,id=n0,tftp=binaries \
+    -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
+
+set -e
+grep -q "Domain-0" smoke.serial || exit 1
+exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:47 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56212.98255 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HL-00012K-2h; Thu, 17 Dec 2020 23:01:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56212.98255; Thu, 17 Dec 2020 23:01:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HK-00012C-Vo; Thu, 17 Dec 2020 23:01:46 +0000
Received: by outflank-mailman (input) for mailman id 56212;
 Thu, 17 Dec 2020 23:01:46 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HK-000123-8z
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:46 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HK-0001U6-8G
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:46 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HK-0006vG-7M
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:46 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6CVmA2e88o/kya6QDtyBP5um/xn1f6nC/ybqiu6A6DA=; b=EpxZXovQAoLcR4WATW6FEY7NlR
	Nf5dDIOJGXM8Hke7s+n187UJ6NrgUpSuktFD0b1qzgvvy7Qu0dHeeicA1HediqizatQpDPJkHXnIN
	O132pqRyxbEfIAv9j4CML/KIaw8GirDeaRvcePek79hgOD7/9HBJa3CN1dEz8xwEiqCc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: use the tests-artifacts kernel for qemu-smoke-arm64-gcc
Message-Id: <E1kq2HK-0006vG-7M@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:46 +0000

commit fccaa4d35c78c08eb351fb3692fff51a61a2a4b0
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:22:17 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: use the tests-artifacts kernel for qemu-smoke-arm64-gcc
    
    Use the tests-artifacts kernel, instead of the Debian kernel, for the
    qemu-smoke-arm64-gcc job.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml         | 1 +
 automation/scripts/qemu-smoke-arm64.sh | 6 ------
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index a291538d68..9448651187 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -55,6 +55,7 @@ qemu-smoke-arm64-gcc:
     - ./automation/scripts/qemu-smoke-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
   dependencies:
     - debian-unstable-gcc-arm64
+    - kernel-5.9.9-arm64-export
   artifacts:
     paths:
       - smoke.serial
diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
index 794c53f887..bdef0717ad 100755
--- a/automation/scripts/qemu-smoke-arm64.sh
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -12,12 +12,6 @@ apt-get -qy install --no-install-recommends qemu-system-aarch64 \
                                             busybox-static \
                                             cpio
 
-cd binaries
-apt-get download linux-image-*[0-9]-arm64
-dpkg -i --ignore-depends=initramfs-tools ./linux-image-*arm64.deb || true
-cp /boot/vmlinuz-*arm64 ./Image
-cd ..
-
 # XXX Silly workaround to get the following QEMU command to work
 # QEMU looks for "efi-virtio.rom" even if it is unneeded
 cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 17 23:01:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 17 Dec 2020 23:01:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56213.98261 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HV-00015D-5I; Thu, 17 Dec 2020 23:01:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56213.98261; Thu, 17 Dec 2020 23:01:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq2HV-000150-1L; Thu, 17 Dec 2020 23:01:57 +0000
Received: by outflank-mailman (input) for mailman id 56213;
 Thu, 17 Dec 2020 23:01:56 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HU-00014r-CK
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:56 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HU-0001UE-BY
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:56 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq2HU-0006vp-AH
 for xen-changelog@lists.xenproject.org; Thu, 17 Dec 2020 23:01:56 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=WZL+pKo9t4oHE8k2sl32Qk2kRYI40Q2v5m1Rvt37E+w=; b=ZCjZGgWzjo/dyTDlHXHooW+jDr
	ENbugVgzYGUgx7YgnxLpyg7uXx9ikBmaP1IeazhZY1fNyCGTvZAz+hncK1SkGQOLG5W6V0Fi1xF9i
	2C0lNb7Br1fItgsEeKjRrMhud96pZv+pKKaHtQ/bQTFbmx9LS8HwYKPwRsTc2aW3Cw7c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] automation: add domU creation to dom0 alpine linux test
Message-Id: <E1kq2HU-0006vp-AH@xenbits.xenproject.org>
Date: Thu, 17 Dec 2020 23:01:56 +0000

commit 7a3b691a8f3aa7720eecaab0e7bd090aa392885a
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:33:14 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add domU creation to dom0 alpine linux test
    
    Add a trivial Busybox based domU.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/qemu-alpine-arm64.sh | 47 +++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/automation/scripts/qemu-alpine-arm64.sh b/automation/scripts/qemu-alpine-arm64.sh
index 62aae2d4c8..b43a654270 100755
--- a/automation/scripts/qemu-alpine-arm64.sh
+++ b/automation/scripts/qemu-alpine-arm64.sh
@@ -8,10 +8,36 @@ apt-get -qy install --no-install-recommends qemu-system-aarch64 \
                                             u-boot-tools \
                                             device-tree-compiler \
                                             cpio \
-                                            curl
+                                            curl \
+                                            busybox-static
 
-mkdir -p binaries/rootfs
-cd binaries/rootfs
+# DomU Busybox
+cd binaries
+mkdir -p initrd
+mkdir -p initrd/bin
+mkdir -p initrd/sbin
+mkdir -p initrd/etc
+mkdir -p initrd/dev
+mkdir -p initrd/proc
+mkdir -p initrd/sys
+mkdir -p initrd/lib
+mkdir -p initrd/var
+mkdir -p initrd/mnt
+cp /bin/busybox initrd/bin/busybox
+initrd/bin/busybox --install initrd/bin
+echo "#!/bin/sh
+
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devtmpfs devtmpfs /dev
+/bin/sh" > initrd/init
+chmod +x initrd/init
+cd initrd
+find . | cpio --create --format='newc' | gzip > ../initrd.cpio.gz
+cd ..
+
+mkdir -p rootfs
+cd rootfs
 tar xvzf ../initrd.tar.gz
 mkdir proc
 mkdir run
@@ -19,6 +45,15 @@ mkdir srv
 mkdir sys
 rm var/run
 cp -ar ../dist/install/* .
+mv ../initrd.cpio.gz ./root
+cp ../Image ./root
+echo "name=\"test\"
+memory=512
+vcpus=1
+kernel=\"/root/Image\"
+ramdisk=\"/root/initrd.cpio.gz\"
+extra=\"console=hvc0 root=/dev/ram0 rdinit=/bin/sh\"
+" > root/test.cfg
 echo "#!/bin/bash
 
 export LD_LIBRARY_PATH=/usr/local/lib
@@ -26,6 +61,8 @@ bash /etc/init.d/xencommons start
 
 xl list
 
+xl create -c /root/test.cfg
+
 " > etc/local.d/xen.start
 chmod +x etc/local.d/xen.start
 echo "rc_verbose=yes" >> etc/rc.conf
@@ -69,7 +106,7 @@ bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/conf
 rm -f smoke.serial
 set +e
 echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
-timeout -k 1 480 \
+timeout -k 1 720 \
 qemu-system-aarch64 \
     -machine virtualization=true \
     -cpu cortex-a57 -machine type=virt \
@@ -81,5 +118,5 @@ qemu-system-aarch64 \
     -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
 
 set -e
-grep -q "Domain-0" smoke.serial || exit 1
+(grep -q "Domain-0" smoke.serial && grep -q "BusyBox" smoke.serial) || exit 1
 exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56307.98503 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Ui-0005D6-Ra; Fri, 18 Dec 2020 06:44:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56307.98503; Fri, 18 Dec 2020 06:44:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Ui-0005Cx-Nz; Fri, 18 Dec 2020 06:44:04 +0000
Received: by outflank-mailman (input) for mailman id 56307;
 Fri, 18 Dec 2020 06:44:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Ug-0005Cs-SU
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Ug-0000gW-Pk
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Ug-0004Uw-NG
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=4vMDcqvoqslKxPuZIQyYUWGRIf5emM1dijobptlHUVQ=; b=u8dErPtjsK3MsloHsnjaumWWzL
	1m9bbBbzkoDzsii9DnNUxO15Vg1nG86c1kyfa4yLNG5A3UKfrUY6kpTgrIrwgu2wA17Y119Rs2skU
	afk0ltutVA4x5cewMLCFPyirzNUm3JX6RYk6lqLMuL2dZb0eREbaRRCzOLM+3eAHnfJs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kq9Ug-0004Uw-NG@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:02 +0000

commit c64ff3b47e44b2a31d04288c5e16059aee8c877b
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:27:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:27:28 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56308.98507 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Us-0005EQ-UK; Fri, 18 Dec 2020 06:44:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56308.98507; Fri, 18 Dec 2020 06:44:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Us-0005EI-RM; Fri, 18 Dec 2020 06:44:14 +0000
Received: by outflank-mailman (input) for mailman id 56308;
 Fri, 18 Dec 2020 06:44:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Uq-0005EA-Tm
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Uq-0000gs-Su
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Uq-0004Vh-Rw
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=r7LkgOINy1m1k2lkdXxa4Lk5d9lS/DIdVcDyKtznBVg=; b=z4BKz82remon16+ymqXXXAD4Up
	pa74sn7moO5w/If8JaMVPd2A01N2eaU80UQ1uXESH7ajo8XpuoElUYg07h7Ju1qP6mpy+vcVH4eTf
	nfhQV29M7wMuLHiKqjOGRZbc6HdxrgYnvThumHeOQpVHGbg7kBW/OI+LA+CeBFpiLjoM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kq9Uq-0004Vh-Rw@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:12 +0000

commit 544a775f8ec48696b3a5207f075d74127d788df4
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:07 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c8e423700d..43900a3914 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 2146f35a6f..a5a71261bc 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 75816dd2c7..e5054294f5 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56309.98510 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9V2-0005Fh-Vm; Fri, 18 Dec 2020 06:44:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56309.98510; Fri, 18 Dec 2020 06:44:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9V2-0005FZ-T1; Fri, 18 Dec 2020 06:44:24 +0000
Received: by outflank-mailman (input) for mailman id 56309;
 Fri, 18 Dec 2020 06:44:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9V1-0005FP-19
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9V1-0000h0-0L
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9V0-0004WK-Uy
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sP0VBTGfyQS5yMFY7hT6dzTQv/VSC2HgOFKHvWW3wGE=; b=ndL2S0kbpBc3qREQSRxM6Kvya3
	oNrK7hjXOIdAKVBp6k1MLI0vDA5ppkNunsY7YNm7JK7i2adHSxsTsm8pKOmUlFTcey7Qsyv7vfsFN
	c6BVJh1PdLJ8LNBSWUDEMkinpr2ZzxvNm8zc9abQrhWqP/prAaYahUQKMxAgjR6889Aw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kq9V0-0004WK-Uy@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:22 +0000

commit 444b7173db0a45df6c2e3dd3f6a58898e8638de3
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:12 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 43900a3914..ec06b4e032 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56310.98515 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VD-0005Gv-1e; Fri, 18 Dec 2020 06:44:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56310.98515; Fri, 18 Dec 2020 06:44:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VC-0005Gm-Ub; Fri, 18 Dec 2020 06:44:34 +0000
Received: by outflank-mailman (input) for mailman id 56310;
 Fri, 18 Dec 2020 06:44:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VB-0005Gd-54
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VB-0000hA-4P
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VB-0004Wz-2U
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jgSR/3m94KeVTcJH5pJi8wsAjSy+A+iRuOk1ELCYN7I=; b=X/+duthmFBZIKd41cXl3ZnRDoJ
	NWO8/SDR78c8H7oTbvbS6kqiOqZvg00yy7QDxlPPJppqhuzSgC8Is27btTvigBzOyMjbDta4DyFRQ
	6TvtIYYuonLdG6wJGFOTIqvp1kfBqHdovU0LHE5kR9dNA/LcXljRb29JFXVKu2kavo6Y=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kq9VB-0004Wz-2U@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:33 +0000

commit 0dbcdcccbc66395179103c8063ca7008f06437e5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:17 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec06b4e032..444dea3cd8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56311.98519 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VN-0005I1-3E; Fri, 18 Dec 2020 06:44:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56311.98519; Fri, 18 Dec 2020 06:44:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VM-0005Ht-WE; Fri, 18 Dec 2020 06:44:45 +0000
Received: by outflank-mailman (input) for mailman id 56311;
 Fri, 18 Dec 2020 06:44:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VL-0005Hk-8n
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VL-0000hb-7F
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VL-0004Xh-6N
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=aStYQ7MLTQQKB66+AfFwhWL+EUKOsAkTzEQptgpHurU=; b=cGubnaDUsszeuL8xrOM0df4y1M
	kOdiThzqfGW4EVkKTSaSTa7sOJ4JfhsAbusv4lLvdgPHSU4lIl9YkJjeZ1uUELqB8TNnRiiIW0bDE
	/Yg7HDpPovamnwl/VKfe6TNjskxXeTtGSBdvt+HTag0eaJYEH+lb1ptb95NUCIZ5aW6k=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kq9VL-0004Xh-6N@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:43 +0000

commit 4739f7941a0c547b26e8ef914ee7b2569f15386d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:23 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 0dc5a40b99..458062856e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:44:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:44:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56312.98523 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VX-0005JF-4h; Fri, 18 Dec 2020 06:44:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56312.98523; Fri, 18 Dec 2020 06:44:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9VX-0005J8-1a; Fri, 18 Dec 2020 06:44:55 +0000
Received: by outflank-mailman (input) for mailman id 56312;
 Fri, 18 Dec 2020 06:44:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VV-0005Iw-BF
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VV-0000hi-A3
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9VV-0004Yd-9L
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:44:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5mci8tUAN4Tbtyed86OXy9jb6hy8xlQd9vKt1u+T2Dk=; b=ZHtqnBdGYfpxTnY+z0KkPO2KZ3
	8F7UrRbS+caIMig8feV/ivFLQ2hzgPVIAzDgS32ETxPiehJgt/ADYlRXAx8lqMgvlx8i+zx/4l1EM
	NQQ1AJeuvkNTSZS+l0QY63qRbvG/zC/adrQyU2WT3UMWyiGcvSc0g/Ou52oOTRIPXWD8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kq9VV-0004Yd-9L@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:44:53 +0000

commit b1efedbec5c721186536db1a7a4d116526e4afdf
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:28 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 444dea3cd8..b4e6744eaf 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index eb1f541188..e25d2c2e53 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56313.98526 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Vh-0005Kf-6a; Fri, 18 Dec 2020 06:45:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56313.98526; Fri, 18 Dec 2020 06:45:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Vh-0005KZ-3P; Fri, 18 Dec 2020 06:45:05 +0000
Received: by outflank-mailman (input) for mailman id 56313;
 Fri, 18 Dec 2020 06:45:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vf-0005KK-EX
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vf-0000iF-D0
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vf-0004b9-C4
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yUD9BJ/zNUex6LIJLaE4PxjD2WVusG7QcYolV088sYA=; b=U1WHWUlP1O4F7RBdTMDyjmLBdu
	ipSe4hrThIKNt5K5awNAp4OxNkJkkJpLW8eFOQoc4jckLk8LR0zY7hppeIlmrKed+29C+McBv8GGq
	8xjVwHcFo9SRsvBkVo3JbBAtVIaQxyyLFssTibJCLN7ajGNP8XtiFo1eVX6BJQzfRixQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: rework node removal
Message-Id: <E1kq9Vf-0004b9-C4@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:03 +0000

commit f1a4126a04d75ac43f223586751a2b163ddb5740
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:33 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b4e6744eaf..6002cad3c4 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 458062856e..cc82864a6e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56314.98531 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Vq-0005MO-9a; Fri, 18 Dec 2020 06:45:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56314.98531; Fri, 18 Dec 2020 06:45:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Vq-0005MI-6c; Fri, 18 Dec 2020 06:45:14 +0000
Received: by outflank-mailman (input) for mailman id 56314;
 Fri, 18 Dec 2020 06:45:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vp-0005M9-Gd
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vp-0000ic-Fu
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vp-0004br-F8
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=VJA9jSpVrZFjX3wKlFArfjjyiQu4yLDfs0k8T+LljqE=; b=5IzkDWTAQ/cyBk4QWvD/4Ipb4w
	pOAvSS9mAC1Xc0xM9RiJ3OEewzV6s8y8cLcLxmDE0ueSRCTVkVb7UCy69zf/63ZNGXPlC/luBLxxt
	ZElJV/cVMRw6ei+zIcFkXZbpv+om71S6b+tCX0+GJVyO7aCrDRh4DAsnP3kPr7GkavcE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kq9Vp-0004br-F8@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:13 +0000

commit aeebc0cf05944557d0ace7db27793bd1d52fc3fe
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:38 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6002cad3c4..fcc3798328 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index cc82864a6e..7ca18e0348 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56315.98535 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9W0-0005Ns-BJ; Fri, 18 Dec 2020 06:45:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56315.98535; Fri, 18 Dec 2020 06:45:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9W0-0005Nk-8B; Fri, 18 Dec 2020 06:45:24 +0000
Received: by outflank-mailman (input) for mailman id 56315;
 Fri, 18 Dec 2020 06:45:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vz-0005Ne-KM
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vz-0000il-Ja
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Vz-0004ch-I6
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jh58XlWoTldxPWdCdDO9k2PgPtSDxjGVP5hE8/zWNug=; b=hf5Qb7Tjv4K/nLn113HtbFlSIr
	vDMJE9nTUhXhQOXryl+crLKRw1XSTYeQyXpCttFHuSOnQmaMC/vlmSonVx3Emt7FXsvNHi1NB0vVC
	GPckxOA4xRXJaCDhgo1qEyodL/yCq4q5V/khS0LRSy+XLL/QjBh7YyDuKQw+pgn88O4c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: introduce node_perms structure
Message-Id: <E1kq9Vz-0004ch-I6@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:23 +0000

commit 9f730200903b7dd663b173233cbb5c2650c4b558
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:43 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index a5a71261bc..ed3b4c7266 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56316.98539 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WA-0005PC-Ca; Fri, 18 Dec 2020 06:45:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56316.98539; Fri, 18 Dec 2020 06:45:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WA-0005P5-9q; Fri, 18 Dec 2020 06:45:34 +0000
Received: by outflank-mailman (input) for mailman id 56316;
 Fri, 18 Dec 2020 06:45:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9W9-0005Oz-NJ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9W9-0000it-MV
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9W9-0004dt-Ll
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/h+324UXTlNlePfjlZPbThpmq4rcLn476HyNQLr3Od4=; b=SE311FhmgQvgi01Sji3Sf6D+oZ
	ivjKBUAxOZrt47SQPfx+in72UqnpmCk7HHa3MqQSswwWmNbYRyNbBQa9mX/g8oq6Mm3zubngUJz1j
	wlL5Izx1V3Ykb+I6q7MgJzrO5UJfBOXrz92U5+4xT9pHYCpKr7aYCKVqpxljVoEqyFsU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kq9W9-0004dt-Ll@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:33 +0000

commit f860f42a41a6ab08e1bffa69b21fe69ba7cca560
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:48 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index f95f44d594..0308b57ff7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ed3b4c7266..44d10e7b88 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 433732b926..8888db697e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -597,6 +600,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -618,6 +674,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7ca18e0348..fc7e5ce3cb 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:44 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56317.98543 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WK-0005QZ-EW; Fri, 18 Dec 2020 06:45:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56317.98543; Fri, 18 Dec 2020 06:45:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WK-0005QS-BW; Fri, 18 Dec 2020 06:45:44 +0000
Received: by outflank-mailman (input) for mailman id 56317;
 Fri, 18 Dec 2020 06:45:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WJ-0005QI-R2
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WJ-0000iw-QH
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WJ-0004f7-Oj
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zrEdl1UTKudmnUY+MwOBxu15x1m2NfUPFRtppnePEew=; b=ALje2M5v3XwYA5LScPzt3fWlod
	3zxpTA8P2sTX+FS4g4x26MiiPZs/73NgfrKFvrppeeadhcNb7aIiDfShNzmIKwVxoRFE4NdXZ/Pqz
	fMFd61H0Rmw/qCi1yL0DYOvV8Ikl5uiQ8Mm5NP6X+lPp63SLEt7eEvr/NiufpXIrpLq8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kq9WJ-0004f7-Oj@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:43 +0000

commit 655190de12e70ccba2107c643de1c527053b0fe8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:53 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0308b57ff7..2a86c4aa5b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 44d10e7b88..897ddab1e2 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 8888db697e..0b2f49ac7d 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -214,7 +214,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -252,7 +252,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -418,7 +418,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e5054294f5..36793b9b1a 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index fc7e5ce3cb..be2479721f 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:45:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:45:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56318.98547 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WU-0005S4-Hv; Fri, 18 Dec 2020 06:45:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56318.98547; Fri, 18 Dec 2020 06:45:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9WU-0005Rw-Ew; Fri, 18 Dec 2020 06:45:54 +0000
Received: by outflank-mailman (input) for mailman id 56318;
 Fri, 18 Dec 2020 06:45:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WT-0005Rq-Tu
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WT-0000iz-TC
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9WT-0004gL-SP
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:45:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=eXJDaZlq8Jt6H2bsU4UR93MvgaJCxZoHD1SGobT8SGQ=; b=L0DP+fgEre+w8aZit4HUY9+Jq/
	WarHaH0ZoNXU6Jv6qHOAgzXzuzacM/N+4vDzHrwMDwovRUVie4UxDz6Vok9QlwwBwpIsFnVZfCeAs
	FJP4PDhReAaPN1R/8XuKBF2uR4RC502ZIRO1F+q4CF5NmCEz5vZslRGhTE6GCsWyG8MA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kq9WT-0004gL-SP@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:45:53 +0000

commit f8443e804c2ab0ae0f8fea7df00c0d51da2f34a1
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:28:59 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:28:59 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 8a7e538893..fb0a6d47c3 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -492,12 +492,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56319.98552 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9We-0005TI-Jz; Fri, 18 Dec 2020 06:46:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56319.98552; Fri, 18 Dec 2020 06:46:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9We-0005TA-GS; Fri, 18 Dec 2020 06:46:04 +0000
Received: by outflank-mailman (input) for mailman id 56319;
 Fri, 18 Dec 2020 06:46:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9We-0005T4-0L
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wd-0000kr-Vu
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wd-0004hq-VE
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xHfhGGVCvVPPeZo8uLSrA84JRnSo38rlu3fSZRCrirk=; b=TmJu++OTExkggUI6v6Vh4ZUs3g
	T7R4wmDlI2n1MpEH76TJQhnik6ihD+GYTh6m/iDHkQWnuUcQGnDEOzC1xV5LHWGJs1F9/ntII+4fa
	NwYSidBn6uBEm5i9S7eysozUnSlFi+81sssG99ZqUx2kuzoojaf8nF5mUjTgUMuuYlHc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kq9Wd-0004hq-VE@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:03 +0000

commit 5e1bac4a10d25a71a868fda7f4c12f9665d694db
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:04 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fb0a6d47c3..56aea4ce30 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56320.98555 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Wo-0005Uy-LK; Fri, 18 Dec 2020 06:46:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56320.98555; Fri, 18 Dec 2020 06:46:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Wo-0005Up-I1; Fri, 18 Dec 2020 06:46:14 +0000
Received: by outflank-mailman (input) for mailman id 56320;
 Fri, 18 Dec 2020 06:46:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wo-0005Uj-3U
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wo-0000lH-2j
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wo-0004ix-1r
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=uo9bJnlYGHi87dcdnLAzvFMSqHQeIdzFrkW0sfH6oY8=; b=jGPxY8BmCZQ6ofUdYAJeY9qI1s
	FwQbe8O5BAHcV23AikWsroeqPLoYfqGKwg79ucJ8YRnqv+9WTZxAn21i3bNc8iigLudAXUSs5jmwq
	RadUs61x3SSq4qROpTIkYDzjUSz7iTbSp0BNi+3FV5QESzJdngmIGA5BSPu1H8kXYtxY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kq9Wo-0004ix-1r@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:14 +0000

commit 551d75d1ff56b7a40c794923c440db7b02f6c207
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:09 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56321.98559 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Wz-0005WI-Ml; Fri, 18 Dec 2020 06:46:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56321.98559; Fri, 18 Dec 2020 06:46:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Wz-0005WB-Jo; Fri, 18 Dec 2020 06:46:25 +0000
Received: by outflank-mailman (input) for mailman id 56321;
 Fri, 18 Dec 2020 06:46:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wy-0005W1-6l
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wy-0000lQ-5c
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Wy-0004kG-4r
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qTjMwY5j0CKHU5EmCXoRCMxcNiRpmMOVwenyl7Y2u8s=; b=HfIPGJBBsIhHzSJauVpvQu3E8N
	qxiTcX+V6rKiBVv8ylLddlxTWo0Eage+FsWqrYKecgKFPfRKHRf8L8ydMVRHGOqYQfvOLvTvDzlQO
	IteVUPlQzjx1GqHtmAWxIQEpDCOAHGAM1T+9drsnzDrzN5wkwKvGLPnaisTMlluaEudM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kq9Wy-0004kG-4r@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:24 +0000

commit bfda5aefa1dfd359136465bf0c0ffacafd080c3e
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:14 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 56aea4ce30..e42460f60a 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -414,7 +414,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -433,7 +433,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56322.98563 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9X9-0005XZ-OK; Fri, 18 Dec 2020 06:46:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56322.98563; Fri, 18 Dec 2020 06:46:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9X9-0005XR-LO; Fri, 18 Dec 2020 06:46:35 +0000
Received: by outflank-mailman (input) for mailman id 56322;
 Fri, 18 Dec 2020 06:46:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9X8-0005XI-9b
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9X8-0000lY-8c
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9X8-0004lK-7o
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Hplc4tHMVTimDteTzul0P6saBPtQGDAgpsrhWw2Xyno=; b=7LsplepJY3kGSC5jPUpemMLCp0
	pXEAxlJ08O2k9t++iB1inPjDjl7gQS0+Hm/k1yWTBhT5kklCVw1tAuQ8Ebxtv6ZVWA0Ft5MoscAJ8
	3EFiJnjsrG43rZZ6XLGYxvQaOftHYp4wnUwE9AEjd7T4CefIzd9c4MQvG1Jz4229qLtg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kq9X8-0004lK-7o@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:34 +0000

commit 674108e2207b37584f7129d6f195599dfc20dc01
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:19 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e42460f60a..5e2347d085 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -414,14 +419,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -433,7 +438,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -501,6 +506,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -542,7 +549,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56323.98567 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9XJ-0005Yr-RT; Fri, 18 Dec 2020 06:46:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56323.98567; Fri, 18 Dec 2020 06:46:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9XJ-0005Yj-ON; Fri, 18 Dec 2020 06:46:45 +0000
Received: by outflank-mailman (input) for mailman id 56323;
 Fri, 18 Dec 2020 06:46:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XI-0005YY-CD
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XI-0000lg-BV
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XI-0004mZ-Aq
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JoLgC2BFOuPWOc/ELMDP2NNlmF6ylwk/0MuJNj0JWkU=; b=MANwCAfhoFz1edQu2Jlsbh4l/c
	2EaT3ffSsQyYPV2iNjdxKoWkOzpjBcSXiKuoQvjW40iFc+T95OVOFcAs26bEWGr/9b7pmD+wVFMSz
	xMpz9aKLE9iSbe7S5fkF7p3RChs3x2+p/BP4hB3gRdV+HwPSNjYzCVakydyk+g2eMXvo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kq9XI-0004mZ-Aq@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:44 +0000

commit d009b8d94eaecb8560a4db132c3f39f96877ac41
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:24 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:46:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:46:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56324.98571 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9XT-0005bf-T0; Fri, 18 Dec 2020 06:46:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56324.98571; Fri, 18 Dec 2020 06:46:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9XT-0005bY-Py; Fri, 18 Dec 2020 06:46:55 +0000
Received: by outflank-mailman (input) for mailman id 56324;
 Fri, 18 Dec 2020 06:46:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XS-0005ac-F5
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XS-0000lo-EJ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9XS-0004np-Dc
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:46:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hUQMziguH/sPyzd42YKZohTTQfzBYfUPm4dhMyK9NBY=; b=42WGnU9yaVPdZ0Ug8pKzno2Os4
	XlckMpqLQyavPTrZFdhcqg2ZYBDk2MSvPZ/q7DQPFR0otb4rKRuXeQJnQipPcYkihPntJ76QfA2tl
	qQwswn420lnMuaBOQijF2Qz1HhN/k5JHOkHD+Ay4Ajhltu9vO1YopPRlccKFJYuUS4D0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kq9XS-0004np-Dc@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:46:54 +0000

commit 9fe89e1ea6b6d415b732fd7ae56dca90ad6fc730
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:29:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:44 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index b0a01b06fa..081076271a 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..8f04cda190 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56325.98575 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xd-0005d0-UR; Fri, 18 Dec 2020 06:47:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56325.98575; Fri, 18 Dec 2020 06:47:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xd-0005cs-Rc; Fri, 18 Dec 2020 06:47:05 +0000
Received: by outflank-mailman (input) for mailman id 56325;
 Fri, 18 Dec 2020 06:47:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xc-0005cf-IY
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xc-0000mC-Hl
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xc-0004p4-GS
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dWIQrexcYN6xaUXc7dizwhdBnO23VVi857ByBpnnKOA=; b=GtqcjJu+jULE+b38HbzBPGaNte
	sZbJgcU9EIqeyNcQQIeF+NyneRTBeoSq0p4QXDlxMZXPZZINQI/34t4PhntNLiInv5Hr0H1J9VhxO
	XKBGyq/7RbzFLYMBqs4qYHY1x3CmikBI5dfgxHzT6tyl0ABvmuk5rT8D2a2sq/aRheuE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kq9Xc-0004p4-GS@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:04 +0000

commit d6d3b136d723001bab11b79e0bc7b318f47a110d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:29:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:49 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 2a86c4aa5b..65291414a3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -670,6 +670,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index be2479721f..b2b77a3f03 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56326.98579 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xn-0005eV-WB; Fri, 18 Dec 2020 06:47:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56326.98579; Fri, 18 Dec 2020 06:47:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xn-0005eN-TA; Fri, 18 Dec 2020 06:47:15 +0000
Received: by outflank-mailman (input) for mailman id 56326;
 Fri, 18 Dec 2020 06:47:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xm-0005eE-ME
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xm-0000mZ-Kk
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xm-0004q0-Jy
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=kJ4Q31EK1bwOjC1BEmFroI2EIAER9iVp5/8DKj9qJ80=; b=LzlVWg7MQMzxLyO4jJRA/ALSvQ
	0HZntnizqz8BGqIR8Q6dty8dxujR1KM0hq8FZ/b+3sxC/hcwUvMD3rvU+JQ8Yo9MMJU3bpCViBwbd
	ZTHrJhRugBM7mIKeTZuu99tezhmHq03JXgOcbtCFP1p2Q/Lkmv/mYaMmbsBbvO+9ShfU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kq9Xm-0004q0-Jy@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:14 +0000

commit 7da93258d45c1d59ac00be61bb52d4ed7d0c064a
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:29:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:29:54 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 65291414a3..cd15b9067c 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1330,6 +1330,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1388,8 +1414,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1446,14 +1474,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1469,6 +1497,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2166,8 +2195,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2179,8 +2209,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 897ddab1e2..cd7993592c 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0b2f49ac7d..28066733cf 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -276,6 +276,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -293,6 +297,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56327.98583 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xy-0005fq-1Q; Fri, 18 Dec 2020 06:47:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56327.98583; Fri, 18 Dec 2020 06:47:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Xx-0005fi-Ug; Fri, 18 Dec 2020 06:47:25 +0000
Received: by outflank-mailman (input) for mailman id 56327;
 Fri, 18 Dec 2020 06:47:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xw-0005fW-OJ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xw-0000mh-NZ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Xw-0004qi-Mt
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=IVXXYy+Mda0Be/dZ6kX7Zh+ZLCs8Uob+jaNnEykd68E=; b=ABi5rDoWCZdb5W4kbd2YLjTHv2
	MSFpj8OA38ZTNLWLRf6C5y2v4c3JlvuNMudyGlCBRJNrPAzU3Qtwc6f3soqQyrTkILDGQZj4Hqgty
	wvxxwSlaHUSXsR0t9B0ZDFGAiOJTLj/uD9/JsSDAsT9sj3aFLWL34Xdgy4PMniad4sFE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kq9Xw-0004qi-Mt@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:24 +0000

commit d4b884bf35f46f3b5efc925847d0144c3e30dee7
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:30:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:16 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 5e2347d085..e07508a2e4 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56328.98587 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Y8-0005hI-4M; Fri, 18 Dec 2020 06:47:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56328.98587; Fri, 18 Dec 2020 06:47:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Y8-0005h9-1H; Fri, 18 Dec 2020 06:47:36 +0000
Received: by outflank-mailman (input) for mailman id 56328;
 Fri, 18 Dec 2020 06:47:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Y6-0005h0-R1
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Y6-0000mp-QE
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Y6-0004rQ-PY
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jKiPVBjugcK/YOZVjHveFN/BvT6UlhuyEwbt6s0Q4PA=; b=1mE1QdTnrCB0qTmMp5wxD4cf6o
	Lr40MoC11lE4L+eRbUJiHPunPWmdVSnO3Xe10lxIuh+T6hoFdm2dxEcjyCCUnYpn50140I93hbZAK
	+k1PmujHG8IeKGbiPgqTONwOU5X0ZC7sSOsihdHEU9nyn1KVsBb7rwR2F6nUvk9OP/lU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kq9Y6-0004rQ-PY@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:34 +0000

commit 3c13a871cb2188958fc41f43bc5c4d28c280cfd2
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:30:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:21 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..ef32f66991 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -430,7 +430,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56329.98591 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9YI-0005ie-5l; Fri, 18 Dec 2020 06:47:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56329.98591; Fri, 18 Dec 2020 06:47:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9YI-0005iW-2t; Fri, 18 Dec 2020 06:47:46 +0000
Received: by outflank-mailman (input) for mailman id 56329;
 Fri, 18 Dec 2020 06:47:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YH-0005iN-0P
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YG-0000my-Vu
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YG-0004sE-Sk
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=H/0MGzNcu3nJBMmzlyq6WDcKCK4PP4aIeETdMMcsB1M=; b=odEI4IndgBSkM25eGL1/mamsG5
	Ipjj8iK4xiUWHM1cCBRbqQQvp9K/JmGnzuSrnrDo3SLnsoWjRiN962sUehRVyGiBsNP1O9H8YFW42
	ozCa5tXE2oSSPCmpy/mZNHlyMrVb4n9xIjRty0iXZ0Xc5JDJyXBffGOwa9Q4IRkNNBTg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kq9YG-0004sE-Sk@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:44 +0000

commit 4943ea778876ac705b4264198663b5f8c9280fb9
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:30:51 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:30:51 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 15 +++++++++++----
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index d5ebfbb83a..d8053ce9bb 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -123,7 +123,7 @@ static void play_dead(void)
     (*dead_idle)();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
 
@@ -163,11 +163,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct page_info *page;
@@ -484,7 +479,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1784,20 +1779,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 281260d181..9578d477b3 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1055,8 +1055,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ad35266a5b..629905d218 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1830,8 +1830,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 079de1e15d..a33bd55adf 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index f3508c3c08..cab3c6ff97 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -124,16 +124,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(__fn)                                      \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            CHECK_FOR_LIVEPATCH_WORK                                      \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (__fn) : "memory" );   \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 5afa1ef6e3..a31de90508 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -318,7 +318,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 371b912887..591c598030 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:47:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:47:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56330.98595 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9YS-0005jo-7U; Fri, 18 Dec 2020 06:47:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56330.98595; Fri, 18 Dec 2020 06:47:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9YS-0005jf-4P; Fri, 18 Dec 2020 06:47:56 +0000
Received: by outflank-mailman (input) for mailman id 56330;
 Fri, 18 Dec 2020 06:47:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YR-0005jX-36
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YR-0000n6-2O
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9YR-0004ss-1h
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:47:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hXdJOgu60j9Be6gaAQiyvZFUbS3AX2vHe07O2GKdhcg=; b=CGD6HVK/YDCOjB/cYtgxH+yxK1
	OdbPixUnUMNfe4/2LP9Uk8QwNivMQFVFofpna8LHxX96jObaqmtdCkQlTl/wb6peVQ4RnUXccHxwn
	WWGEwwSRVeo9qb+ZGhdXalXnkq+VVEcwZSQWHcNS7rBLEJGvc684oQnoeNWRm2OEOPoU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kq9YR-0004ss-1h@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:47:55 +0000

commit 51e9505a55f9f706516d959f76386df7a8877595
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:31:31 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:31:31 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:48:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:48:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56331.98599 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Yc-0005lD-9J; Fri, 18 Dec 2020 06:48:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56331.98599; Fri, 18 Dec 2020 06:48:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Yc-0005l1-5y; Fri, 18 Dec 2020 06:48:06 +0000
Received: by outflank-mailman (input) for mailman id 56331;
 Fri, 18 Dec 2020 06:48:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yb-0005ku-5q
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yb-0000na-5B
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yb-0004to-4U
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=yFQr/vOctfiVLKAWCOXlING81bi0NUAVauz/iTW3hQE=; b=Cx/10UCuN7l/NIi0osn+cK/Dvu
	aEMtDgjeIxjURJbn/wntjDOvZN9zzRdjRfkd9VxBshjNsLaLbLRWH4wv7abSksXCnV3/B6H945sBL
	cb3SaQvXSqIlXIL2IMHWfqiBEqxPUponi0CBmfU5pfXxKEygrszs6VOdvmiDdtktoZnY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kq9Yb-0004to-4U@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:48:05 +0000

commit 2186c16b25402c8165d7e41ee5656bd4f94f4d6b
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:31:56 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:31:56 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:48:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:48:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56332.98603 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Ym-0005mf-Ak; Fri, 18 Dec 2020 06:48:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56332.98603; Fri, 18 Dec 2020 06:48:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Ym-0005mX-7b; Fri, 18 Dec 2020 06:48:16 +0000
Received: by outflank-mailman (input) for mailman id 56332;
 Fri, 18 Dec 2020 06:48:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yl-0005mO-8w
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yl-0000o1-8A
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yl-0004ue-7T
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=rdMEmuk3JLkN+9/KkjSBsfGkdF2J9HDjDklPbYlo0qg=; b=zH7wZmn0lfnsbgPz0WtL3OrkdU
	IbNWDy2BdqByUeaWEmnfrssT3l0c3OC+nWBiWX0jRk1sgpVfo2ymhyJT0tg1fHyJbEojsxISFnpbK
	5bLQYcM8YOcZ3xhl0l17AHRQ8L3XUd50CQz2zp8zebA1WtWTXIrnL1eQeboQl4xATNh4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kq9Yl-0004ue-7T@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:48:15 +0000

commit c8b97ff6797f594421e8ed86fc2dd09b70424457
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:33:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:33:11 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cd15b9067c..0737c55528 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1249,8 +1259,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1951,6 +1965,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1971,6 +1986,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1993,7 +2009,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2035,6 +2051,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 28066733cf..44562e819f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -200,6 +206,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -221,21 +230,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -309,58 +331,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -407,15 +455,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid, mfn);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -526,8 +580,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -670,8 +724,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -752,6 +808,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 36793b9b1a..9fcb4c9ba9 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 06:48:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 06:48:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56333.98607 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Yw-0005oC-DR; Fri, 18 Dec 2020 06:48:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56333.98607; Fri, 18 Dec 2020 06:48:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kq9Yw-0005o4-AU; Fri, 18 Dec 2020 06:48:26 +0000
Received: by outflank-mailman (input) for mailman id 56333;
 Fri, 18 Dec 2020 06:48:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yv-0005nx-BX
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yv-0000oC-Aq
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kq9Yv-0004vO-AD
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 06:48:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Y9gWrB6vYTBNP5pJO4WiYkxQS+XklIxFhZVA/OluoS4=; b=U8zRITefyO0F6ntXnUfeGZ9HkH
	pYKQwkmW+yzVdNIcpaDYYxyiFeAQkV3qbLR836ezHHOWQtlXn93wQCcNieVrc5iP3JDRV6oMinMoB
	sekAoJvjOeuJVlb0we5CLnAO68Gmtzao7uFoqGEOi6iFCPfGsFzWtBa5iqjvxhhiI5sU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.12] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kq9Yv-0004vO-AD@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 06:48:25 +0000

commit 2525a745e18bbf14b4f7b1b18209a0ab9166178d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:33:16 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:33:16 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e07508a2e4..f51979926a 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -437,6 +437,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index ef32f66991..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -436,6 +443,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 8f04cda190..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,6 +341,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:12 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56483.98887 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwT-0000oU-Qr; Fri, 18 Dec 2020 12:33:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56483.98887; Fri, 18 Dec 2020 12:33:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwT-0000oM-O4; Fri, 18 Dec 2020 12:33:05 +0000
Received: by outflank-mailman (input) for mailman id 56483;
 Fri, 18 Dec 2020 12:33:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwS-0000oH-RR
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwS-0007AD-No
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwS-0006ty-LP
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Op7EPpPH18eaoF6FAvD8k0KFOGmD8r+O8LHTc9I0V5I=; b=3ox4Chx11RyTjXTqNBV/dYn2ux
	4i13ka2ywqyOzQCj1KDAdS/FwK2/JnbvGLWxjnmVheJwamIsz1Y9n+OetTLwNyI9IKC3OaGBTbtoZ
	XqRLm+onRU43nYHaafz7Ews/Z/86ZqABFZy/diuaGw+QitXpXUw/DYuSwdQLEBZD0q5c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: collect library files in an archive
Message-Id: <E1kqEwS-0006ty-LP@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:04 +0000

commit f301f9a9e84f3cfd18750065f8a3794c8182c7f0
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:17:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:17:57 2020 +0100

    lib: collect library files in an archive
    
    In order to (subsequently) drop odd things like CONFIG_NEEDS_LIST_SORT
    just to avoid bloating binaries when only some arch-es and/or
    configurations need generic library routines, combine objects under lib/
    into an archive, which the linker then can pick the necessary objects
    out of.
    
    Note that we can't use thin archives just yet, until we've raised the
    minimum required binutils version suitably.
    
    Note further that --start-group / --end-group get put in place right
    away to allow for symbol resolution across all archives, once we gain
    multuiple ones.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/Rules.mk          | 29 +++++++++++++++++++++++++----
 xen/arch/arm/Makefile |  6 +++---
 xen/arch/x86/Makefile |  8 ++++----
 xen/lib/Makefile      |  3 ++-
 4 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index d5e5eb33de..aba6ca2a90 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -41,12 +41,16 @@ ALL_OBJS-y               += $(BASEDIR)/xsm/built_in.o
 ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
 ALL_OBJS-$(CONFIG_CRYPTO)   += $(BASEDIR)/crypto/built_in.o
 
+ALL_LIBS-y               := $(BASEDIR)/lib/lib.a
+
 # Initialise some variables
+lib-y :=
 targets :=
 CFLAGS-y :=
 AFLAGS-y :=
 
 ALL_OBJS := $(ALL_OBJS-y)
+ALL_LIBS := $(ALL_LIBS-y)
 
 SPECIAL_DATA_SECTIONS := rodata $(foreach a,1 2 4 8 16, \
                                             $(foreach w,1 2 4, \
@@ -60,7 +64,14 @@ include Makefile
 # ---------------------------------------------------------------------------
 
 quiet_cmd_ld = LD      $@
-cmd_ld = $(LD) $(XEN_LDFLAGS) -r -o $@ $(real-prereqs)
+cmd_ld = $(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out %.a,$(real-prereqs)) \
+               --start-group $(filter %.a,$(real-prereqs)) --end-group
+
+# Archive
+# ---------------------------------------------------------------------------
+
+quiet_cmd_ar = AR      $@
+cmd_ar = rm -f $@; $(AR) cPrs $@ $(real-prereqs)
 
 # Objcopy
 # ---------------------------------------------------------------------------
@@ -86,6 +97,10 @@ obj-y    := $(patsubst %/, %/built_in.o, $(obj-y))
 # tell kbuild to descend
 subdir-obj-y := $(filter %/built_in.o, $(obj-y))
 
+# Libraries are always collected in one lib file.
+# Filter out objects already built-in
+lib-y := $(filter-out $(obj-y), $(sort $(lib-y)))
+
 $(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): CFLAGS-y += -DINIT_SECTIONS_ONLY
 
 ifeq ($(CONFIG_COVERAGE),y)
@@ -129,7 +144,7 @@ include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
 c_flags += $(CFLAGS-y)
 a_flags += $(CFLAGS-y) $(AFLAGS-y)
 
-built_in.o: $(obj-y) $(extra-y)
+built_in.o: $(obj-y) $(if $(strip $(lib-y)),lib.a) $(extra-y)
 ifeq ($(strip $(obj-y)),)
 	$(CC) $(c_flags) -c -x c /dev/null -o $@
 else
@@ -140,8 +155,14 @@ else
 endif
 endif
 
+lib.a: $(lib-y) FORCE
+	$(call if_changed,ar)
+
 targets += built_in.o
-targets += $(filter-out $(subdir-obj-y), $(obj-y)) $(extra-y)
+ifneq ($(strip $(lib-y)),)
+targets += lib.a
+endif
+targets += $(filter-out $(subdir-obj-y), $(obj-y) $(lib-y)) $(extra-y)
 targets += $(MAKECMDGOALS)
 
 built_in_bin.o: $(obj-bin-y) $(extra-y)
@@ -155,7 +176,7 @@ endif
 PHONY += FORCE
 FORCE:
 
-%/built_in.o: FORCE
+%/built_in.o %/lib.a: FORCE
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C $* built_in.o
 
 %/built_in_bin.o: FORCE
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index ad2d497c45..512ffdd781 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -90,14 +90,14 @@ endif
 
 ifeq ($(CONFIG_LTO),y)
 # Gather all LTO objects together
-prelink_lto.o: $(ALL_OBJS)
-	$(LD_LTO) -r -o $@ $^
+prelink_lto.o: $(ALL_OBJS) $(ALL_LIBS)
+	$(LD_LTO) -r -o $@ $(filter-out %.a,$^) --start-group $(filter %.a,$^) --end-group
 
 # Link it with all the binary objects
 prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o
 	$(call if_changed,ld)
 else
-prelink.o: $(ALL_OBJS) FORCE
+prelink.o: $(ALL_OBJS) $(ALL_LIBS) FORCE
 	$(call if_changed,ld)
 endif
 
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 9b368632fb..8f2180485b 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -132,8 +132,8 @@ EFI_OBJS-$(XEN_BUILD_EFI) := efi/relocs-dummy.o
 
 ifeq ($(CONFIG_LTO),y)
 # Gather all LTO objects together
-prelink_lto.o: $(ALL_OBJS)
-	$(LD_LTO) -r -o $@ $^
+prelink_lto.o: $(ALL_OBJS) $(ALL_LIBS)
+	$(LD_LTO) -r -o $@ $(filter-out %.a,$^) --start-group $(filter %.a,$^) --end-group
 
 # Link it with all the binary objects
 prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o $(EFI_OBJS-y) FORCE
@@ -142,10 +142,10 @@ prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o $
 prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o FORCE
 	$(call if_changed,ld)
 else
-prelink.o: $(ALL_OBJS) $(EFI_OBJS-y) FORCE
+prelink.o: $(ALL_OBJS) $(ALL_LIBS) $(EFI_OBJS-y) FORCE
 	$(call if_changed,ld)
 
-prelink-efi.o: $(ALL_OBJS) FORCE
+prelink-efi.o: $(ALL_OBJS) $(ALL_LIBS) FORCE
 	$(call if_changed,ld)
 endif
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 53b1da025e..b8814361d6 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,2 +1,3 @@
-obj-y += ctype.o
 obj-$(CONFIG_X86) += x86/
+
+lib-y += ctype.o
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56484.98892 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwd-0000pZ-Se; Fri, 18 Dec 2020 12:33:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56484.98892; Fri, 18 Dec 2020 12:33:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwd-0000pR-Pg; Fri, 18 Dec 2020 12:33:15 +0000
Received: by outflank-mailman (input) for mailman id 56484;
 Fri, 18 Dec 2020 12:33:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwc-0000pK-T3
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwc-0007AW-Rn
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwc-0006um-Pw
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=qW6tCy80tAUsDYo9VaN8Dxkuy5jYWkKE1Fkfhzwo6V0=; b=DZ9drmqgbF/d9Zzui7UKkCDcez
	zzQnRmvr/dBKfJv361+3Ryos2c8Mk+4p07+mIcJLQJEIczllKHSTH/IlWB8dMBlHQdOH6e6UyVlYA
	xxgfxbH74TxaS9hWB0Fomhu2sbMdyTZ6hJ/uTxlrXGzxhwEbasEotKt8/XFk1Hx1s2Pg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move list sorting code
Message-Id: <E1kqEwc-0006um-Pw@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:14 +0000

commit 26dfde919cac720c29d076bc8fd38ad0af1b2abb
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:20:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:20:42 2020 +0100

    lib: move list sorting code
    
    Build the source file always, as by putting it into an archive it still
    won't be linked into final binaries when not needed. This way possible
    build breakage will be easier to notice, and it's more consistent with
    us unconditionally building other library kind of code (e.g. sort() or
    bsearch()).
    
    While moving the source file, take the opportunity and drop the
    pointless EXPORT_SYMBOL() and an unnecessary #include.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/arch/arm/Kconfig   |   4 +-
 xen/common/Kconfig     |   3 -
 xen/common/Makefile    |   1 -
 xen/common/list_sort.c | 157 -------------------------------------------------
 xen/lib/Makefile       |   1 +
 xen/lib/list-sort.c    | 155 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 157 insertions(+), 164 deletions(-)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 41bde2f401..c3eb13ea73 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -56,9 +56,7 @@ config HVM
         def_bool y
 
 config NEW_VGIC
-	bool
-	prompt "Use new VGIC implementation"
-	select NEEDS_LIST_SORT
+	bool "Use new VGIC implementation"
 	---help---
 
 	This is an alternative implementation of the ARM GIC interrupt
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 3e2cf25088..0661328a99 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -66,9 +66,6 @@ config MEM_ACCESS
 config NEEDS_LIBELF
 	bool
 
-config NEEDS_LIST_SORT
-	bool
-
 menu "Speculative hardening"
 
 config SPECULATIVE_HARDEN_ARRAY
diff --git a/xen/common/Makefile b/xen/common/Makefile
index d109f279a4..332e7d667c 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -21,7 +21,6 @@ obj-y += keyhandler.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_KEXEC) += kimage.o
 obj-y += lib.o
-obj-$(CONFIG_NEEDS_LIST_SORT) += list_sort.o
 obj-$(CONFIG_LIVEPATCH) += livepatch.o livepatch_elf.o
 obj-$(CONFIG_MEM_ACCESS) += mem_access.o
 obj-y += memory.o
diff --git a/xen/common/list_sort.c b/xen/common/list_sort.c
deleted file mode 100644
index af2b2f6519..0000000000
--- a/xen/common/list_sort.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * list_sort.c: merge sort implementation for linked lists
- * Copied from the Linux kernel (lib/list_sort.c)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <xen/lib.h>
-#include <xen/list.h>
-
-#define MAX_LIST_LENGTH_BITS 20
-
-/*
- * Returns a list organized in an intermediate format suited
- * to chaining of merge() calls: null-terminated, no reserved or
- * sentinel head node, "prev" links not maintained.
- */
-static struct list_head *merge(void *priv,
-				int (*cmp)(void *priv, struct list_head *a,
-					struct list_head *b),
-				struct list_head *a, struct list_head *b)
-{
-	struct list_head head, *tail = &head;
-
-	while (a && b) {
-		/* if equal, take 'a' -- important for sort stability */
-		if ((*cmp)(priv, a, b) <= 0) {
-			tail->next = a;
-			a = a->next;
-		} else {
-			tail->next = b;
-			b = b->next;
-		}
-		tail = tail->next;
-	}
-	tail->next = a?:b;
-	return head.next;
-}
-
-/*
- * Combine final list merge with restoration of standard doubly-linked
- * list structure.  This approach duplicates code from merge(), but
- * runs faster than the tidier alternatives of either a separate final
- * prev-link restoration pass, or maintaining the prev links
- * throughout.
- */
-static void merge_and_restore_back_links(void *priv,
-				int (*cmp)(void *priv, struct list_head *a,
-					struct list_head *b),
-				struct list_head *head,
-				struct list_head *a, struct list_head *b)
-{
-	struct list_head *tail = head;
-	u8 count = 0;
-
-	while (a && b) {
-		/* if equal, take 'a' -- important for sort stability */
-		if ((*cmp)(priv, a, b) <= 0) {
-			tail->next = a;
-			a->prev = tail;
-			a = a->next;
-		} else {
-			tail->next = b;
-			b->prev = tail;
-			b = b->next;
-		}
-		tail = tail->next;
-	}
-	tail->next = a ? : b;
-
-	do {
-		/*
-		 * In worst cases this loop may run many iterations.
-		 * Continue callbacks to the client even though no
-		 * element comparison is needed, so the client's cmp()
-		 * routine can invoke cond_resched() periodically.
-		 */
-		if (unlikely(!(++count)))
-			(*cmp)(priv, tail->next, tail->next);
-
-		tail->next->prev = tail;
-		tail = tail->next;
-	} while (tail->next);
-
-	tail->next = head;
-	head->prev = tail;
-}
-
-/**
- * list_sort - sort a list
- * @priv: private data, opaque to list_sort(), passed to @cmp
- * @head: the list to sort
- * @cmp: the elements comparison function
- *
- * This function implements "merge sort", which has O(nlog(n))
- * complexity.
- *
- * The comparison function @cmp must return a negative value if @a
- * should sort before @b, and a positive value if @a should sort after
- * @b. If @a and @b are equivalent, and their original relative
- * ordering is to be preserved, @cmp must return 0.
- */
-void list_sort(void *priv, struct list_head *head,
-		int (*cmp)(void *priv, struct list_head *a,
-			struct list_head *b))
-{
-	struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
-						-- last slot is a sentinel */
-	int lev;  /* index into part[] */
-	int max_lev = 0;
-	struct list_head *list;
-
-	if (list_empty(head))
-		return;
-
-	memset(part, 0, sizeof(part));
-
-	head->prev->next = NULL;
-	list = head->next;
-
-	while (list) {
-		struct list_head *cur = list;
-		list = list->next;
-		cur->next = NULL;
-
-		for (lev = 0; part[lev]; lev++) {
-			cur = merge(priv, cmp, part[lev], cur);
-			part[lev] = NULL;
-		}
-		if (lev > max_lev) {
-			if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
-				dprintk(XENLOG_DEBUG,
-					"list too long for efficiency\n");
-				lev--;
-			}
-			max_lev = lev;
-		}
-		part[lev] = cur;
-	}
-
-	for (lev = 0; lev < max_lev; lev++)
-		if (part[lev])
-			list = merge(priv, cmp, part[lev], list);
-
-	merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
-}
-EXPORT_SYMBOL(list_sort);
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index b8814361d6..764f3624b5 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_X86) += x86/
 
 lib-y += ctype.o
+lib-y += list-sort.o
diff --git a/xen/lib/list-sort.c b/xen/lib/list-sort.c
new file mode 100644
index 0000000000..f8d8bbf281
--- /dev/null
+++ b/xen/lib/list-sort.c
@@ -0,0 +1,155 @@
+/*
+ * list_sort.c: merge sort implementation for linked lists
+ * Copied from the Linux kernel (lib/list_sort.c)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/list.h>
+
+#define MAX_LIST_LENGTH_BITS 20
+
+/*
+ * Returns a list organized in an intermediate format suited
+ * to chaining of merge() calls: null-terminated, no reserved or
+ * sentinel head node, "prev" links not maintained.
+ */
+static struct list_head *merge(void *priv,
+				int (*cmp)(void *priv, struct list_head *a,
+					struct list_head *b),
+				struct list_head *a, struct list_head *b)
+{
+	struct list_head head, *tail = &head;
+
+	while (a && b) {
+		/* if equal, take 'a' -- important for sort stability */
+		if ((*cmp)(priv, a, b) <= 0) {
+			tail->next = a;
+			a = a->next;
+		} else {
+			tail->next = b;
+			b = b->next;
+		}
+		tail = tail->next;
+	}
+	tail->next = a?:b;
+	return head.next;
+}
+
+/*
+ * Combine final list merge with restoration of standard doubly-linked
+ * list structure.  This approach duplicates code from merge(), but
+ * runs faster than the tidier alternatives of either a separate final
+ * prev-link restoration pass, or maintaining the prev links
+ * throughout.
+ */
+static void merge_and_restore_back_links(void *priv,
+				int (*cmp)(void *priv, struct list_head *a,
+					struct list_head *b),
+				struct list_head *head,
+				struct list_head *a, struct list_head *b)
+{
+	struct list_head *tail = head;
+	u8 count = 0;
+
+	while (a && b) {
+		/* if equal, take 'a' -- important for sort stability */
+		if ((*cmp)(priv, a, b) <= 0) {
+			tail->next = a;
+			a->prev = tail;
+			a = a->next;
+		} else {
+			tail->next = b;
+			b->prev = tail;
+			b = b->next;
+		}
+		tail = tail->next;
+	}
+	tail->next = a ? : b;
+
+	do {
+		/*
+		 * In worst cases this loop may run many iterations.
+		 * Continue callbacks to the client even though no
+		 * element comparison is needed, so the client's cmp()
+		 * routine can invoke cond_resched() periodically.
+		 */
+		if (unlikely(!(++count)))
+			(*cmp)(priv, tail->next, tail->next);
+
+		tail->next->prev = tail;
+		tail = tail->next;
+	} while (tail->next);
+
+	tail->next = head;
+	head->prev = tail;
+}
+
+/**
+ * list_sort - sort a list
+ * @priv: private data, opaque to list_sort(), passed to @cmp
+ * @head: the list to sort
+ * @cmp: the elements comparison function
+ *
+ * This function implements "merge sort", which has O(nlog(n))
+ * complexity.
+ *
+ * The comparison function @cmp must return a negative value if @a
+ * should sort before @b, and a positive value if @a should sort after
+ * @b. If @a and @b are equivalent, and their original relative
+ * ordering is to be preserved, @cmp must return 0.
+ */
+void list_sort(void *priv, struct list_head *head,
+		int (*cmp)(void *priv, struct list_head *a,
+			struct list_head *b))
+{
+	struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
+						-- last slot is a sentinel */
+	int lev;  /* index into part[] */
+	int max_lev = 0;
+	struct list_head *list;
+
+	if (list_empty(head))
+		return;
+
+	memset(part, 0, sizeof(part));
+
+	head->prev->next = NULL;
+	list = head->next;
+
+	while (list) {
+		struct list_head *cur = list;
+		list = list->next;
+		cur->next = NULL;
+
+		for (lev = 0; part[lev]; lev++) {
+			cur = merge(priv, cmp, part[lev], cur);
+			part[lev] = NULL;
+		}
+		if (lev > max_lev) {
+			if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
+				dprintk(XENLOG_DEBUG,
+					"list too long for efficiency\n");
+				lev--;
+			}
+			max_lev = lev;
+		}
+		part[lev] = cur;
+	}
+
+	for (lev = 0; lev < max_lev; lev++)
+		if (part[lev])
+			list = merge(priv, cmp, part[lev], list);
+
+	merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
+}
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56485.98896 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwn-0000qq-UQ; Fri, 18 Dec 2020 12:33:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56485.98896; Fri, 18 Dec 2020 12:33:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwn-0000qi-RL; Fri, 18 Dec 2020 12:33:25 +0000
Received: by outflank-mailman (input) for mailman id 56485;
 Fri, 18 Dec 2020 12:33:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwm-0000qb-Va
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwm-0007Ah-Uo
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwm-0006vg-Tm
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zbAAqS6K4bWfx2lZHMIl20g8RVlZe5vY7aDk5qwxUqw=; b=46mLngUYg66EWBoIDY5tazCXvI
	Tt/JQe+PrtuJEB41DsD1A1sRk2FamYr9CSrxjvGpItlpfRobPqn5QK+o+wizvoN4wJDcF9gQn6ef6
	9vfrzXBqTJ1zXDlkA1vcqhLAx5RDLcwWomFaNWlPkzzu+1kwSELohEDDtKlrUgRw5JXk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move parse_size_and_unit()
Message-Id: <E1kqEwm-0006vg-Tm@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:24 +0000

commit 65fdf25768deba4e8bea751773f2ec4f7ff67ea5
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:21:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:21:25 2020 +0100

    lib: move parse_size_and_unit()
    
    ... into its own CU, to build it into an archive.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/lib.c     | 39 ---------------------------------------
 xen/lib/Makefile     |  1 +
 xen/lib/parse-size.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 39 deletions(-)

diff --git a/xen/common/lib.c b/xen/common/lib.c
index a224efa8f6..6cfa332142 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -423,45 +423,6 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 #endif
 }
 
-unsigned long long parse_size_and_unit(const char *s, const char **ps)
-{
-    unsigned long long ret;
-    const char *s1;
-
-    ret = simple_strtoull(s, &s1, 0);
-
-    switch ( *s1 )
-    {
-    case 'T': case 't':
-        ret <<= 10;
-        /* fallthrough */
-    case 'G': case 'g':
-        ret <<= 10;
-        /* fallthrough */
-    case 'M': case 'm':
-        ret <<= 10;
-        /* fallthrough */
-    case 'K': case 'k':
-        ret <<= 10;
-        /* fallthrough */
-    case 'B': case 'b':
-        s1++;
-        break;
-    case '%':
-        if ( ps )
-            break;
-        /* fallthrough */
-    default:
-        ret <<= 10; /* default to kB */
-        break;
-    }
-
-    if ( ps != NULL )
-        *ps = s1;
-
-    return ret;
-}
-
 typedef void (*ctor_func_t)(void);
 extern const ctor_func_t __ctors_start[], __ctors_end[];
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 764f3624b5..99f857540c 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_X86) += x86/
 
 lib-y += ctype.o
 lib-y += list-sort.o
+lib-y += parse-size.o
diff --git a/xen/lib/parse-size.c b/xen/lib/parse-size.c
new file mode 100644
index 0000000000..ec980cadff
--- /dev/null
+++ b/xen/lib/parse-size.c
@@ -0,0 +1,50 @@
+#include <xen/lib.h>
+
+unsigned long long parse_size_and_unit(const char *s, const char **ps)
+{
+    unsigned long long ret;
+    const char *s1;
+
+    ret = simple_strtoull(s, &s1, 0);
+
+    switch ( *s1 )
+    {
+    case 'T': case 't':
+        ret <<= 10;
+        /* fallthrough */
+    case 'G': case 'g':
+        ret <<= 10;
+        /* fallthrough */
+    case 'M': case 'm':
+        ret <<= 10;
+        /* fallthrough */
+    case 'K': case 'k':
+        ret <<= 10;
+        /* fallthrough */
+    case 'B': case 'b':
+        s1++;
+        break;
+    case '%':
+        if ( ps )
+            break;
+        /* fallthrough */
+    default:
+        ret <<= 10; /* default to kB */
+        break;
+    }
+
+    if ( ps != NULL )
+        *ps = s1;
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56486.98900 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwx-0000sU-WC; Fri, 18 Dec 2020 12:33:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56486.98900; Fri, 18 Dec 2020 12:33:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEwx-0000sL-Sv; Fri, 18 Dec 2020 12:33:35 +0000
Received: by outflank-mailman (input) for mailman id 56486;
 Fri, 18 Dec 2020 12:33:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwx-0000sC-2i
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwx-0007At-1v
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEwx-0006wO-0X
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=uHqDroXEhDLRUoPoGmT5KlSemCrTrM1oCZadfYY37/s=; b=Wjl5TPBmnjxCqLZJu3Co1Li6OJ
	MmLrAJbN4SmIR8Hbdzv30bqXxQ884YlnxII7oR5ryIdEzer6RiC7CW8nZtsQulner0YxJWM83Jv9X
	LP1XDSTe/NRXDxXkAee8737iVSynVJ1tJZWCG+gOkcMk5Qo47evznzU1gdQIJUxYBgGs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move init_constructors()
Message-Id: <E1kqEwx-0006wO-0X@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:35 +0000

commit 3b1d8eb4744d210abcd1c033bf07d20345b926ba
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:22:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:22:10 2020 +0100

    lib: move init_constructors()
    
    ... into its own CU, for being unrelated to other things in
    common/lib.c.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/lib.c | 14 --------------
 xen/lib/Makefile |  1 +
 xen/lib/ctors.c  | 25 +++++++++++++++++++++++++
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/xen/common/lib.c b/xen/common/lib.c
index 6cfa332142..f5ca179a0a 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -1,6 +1,5 @@
 #include <xen/lib.h>
 #include <xen/types.h>
-#include <xen/init.h>
 #include <asm/byteorder.h>
 
 /*
@@ -423,19 +422,6 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 #endif
 }
 
-typedef void (*ctor_func_t)(void);
-extern const ctor_func_t __ctors_start[], __ctors_end[];
-
-void __init init_constructors(void)
-{
-    const ctor_func_t *f;
-    for ( f = __ctors_start; f < __ctors_end; ++f )
-        (*f)();
-
-    /* Putting this here seems as good (or bad) as any other place. */
-    BUILD_BUG_ON(sizeof(size_t) != sizeof(ssize_t));
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 99f857540c..72c72fffec 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_X86) += x86/
 
+lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
diff --git a/xen/lib/ctors.c b/xen/lib/ctors.c
new file mode 100644
index 0000000000..5bdc591cd5
--- /dev/null
+++ b/xen/lib/ctors.c
@@ -0,0 +1,25 @@
+#include <xen/init.h>
+#include <xen/lib.h>
+
+typedef void (*ctor_func_t)(void);
+extern const ctor_func_t __ctors_start[], __ctors_end[];
+
+void __init init_constructors(void)
+{
+    const ctor_func_t *f;
+    for ( f = __ctors_start; f < __ctors_end; ++f )
+        (*f)();
+
+    /* Putting this here seems as good (or bad) as any other place. */
+    BUILD_BUG_ON(sizeof(size_t) != sizeof(ssize_t));
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56487.98903 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEx8-0000u0-2r; Fri, 18 Dec 2020 12:33:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56487.98903; Fri, 18 Dec 2020 12:33:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqEx7-0000ts-Vx; Fri, 18 Dec 2020 12:33:45 +0000
Received: by outflank-mailman (input) for mailman id 56487;
 Fri, 18 Dec 2020 12:33:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEx7-0000tj-7J
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEx7-0007B7-5i
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqEx7-0006xS-42
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ns9F/X1/C+LqQVnrQSC7aoRqqyxeO7HEsbEOTr+a+jY=; b=a+WHcd+qvMQwGGH7hMrd/n9UCd
	Nz9tu7qXHF3dKTFkxuegl27w4o0OHiT4dVcPt1f/DGQdrS/n9tabDikCJWEj3KqCuQtEIaHf3pNJE
	pDuFMAHeggRK41K+h3O6bgAWhg8XGpQMr4yleiH3+EEqq12DERgBzZaw6qrMIhlWYRWE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move rbtree code
Message-Id: <E1kqEx7-0006xS-42@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:45 +0000

commit c54212261dc3305429344fe1d1cb298b30830155
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:22:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:22:54 2020 +0100

    lib: move rbtree code
    
    Build this code into an archive, which results in not linking it into
    x86 final binaries. This saves about 1.5k of dead code.
    
    While moving the source file, take the opportunity and drop the
    pointless EXPORT_SYMBOL() and an instance of trailing whitespace.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile |   1 -
 xen/common/rbtree.c | 577 ----------------------------------------------------
 xen/lib/Makefile    |   1 +
 xen/lib/rbtree.c    | 570 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 571 insertions(+), 578 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index 332e7d667c..d65c9fe9cb 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -33,7 +33,6 @@ obj-y += preempt.o
 obj-y += random.o
 obj-y += rangeset.o
 obj-y += radix-tree.o
-obj-y += rbtree.o
 obj-y += rcupdate.o
 obj-y += rwlock.o
 obj-y += shutdown.o
diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
deleted file mode 100644
index 9f5498a89d..0000000000
--- a/xen/common/rbtree.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
-  Red Black Trees
-  (C) 1999  Andrea Arcangeli <andrea@suse.de>
-  (C) 2002  David Woodhouse <dwmw2@infradead.org>
-  (C) 2012  Michel Lespinasse <walken@google.com>
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-  linux/lib/rbtree.c
-*/
-
-#include <xen/types.h>
-#include <xen/rbtree.h>
-
-/*
- * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree 
- *
- *  1) A node is either red or black
- *  2) The root is black
- *  3) All leaves (NULL) are black
- *  4) Both children of every red node are black
- *  5) Every simple path from root to leaves contains the same number
- *     of black nodes.
- *
- *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
- *  consecutive red nodes in a path and every red node is therefore followed by
- *  a black. So if B is the number of black nodes on every simple path (as per
- *  5), then the longest possible path due to 4 is 2B.
- *
- *  We shall indicate color with case, where black nodes are uppercase and red
- *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
- *  parentheses and have some accompanying text comment.
- */
-
-#define		RB_RED		0
-#define		RB_BLACK	1
-
-#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
-
-#define __rb_color(pc)     ((pc) & 1)
-#define __rb_is_black(pc)  __rb_color(pc)
-#define __rb_is_red(pc)    (!__rb_color(pc))
-#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
-#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
-#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
-
-static inline void rb_set_black(struct rb_node *rb)
-{
-	rb->__rb_parent_color |= RB_BLACK;
-}
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
-}
-
-static inline void rb_set_parent_color(struct rb_node *rb,
-				      struct rb_node *p, int color)
-{
-	rb->__rb_parent_color = (unsigned long)p | color;
-}
-
-static inline struct rb_node *rb_red_parent(struct rb_node *red)
-{
-	return (struct rb_node *)red->__rb_parent_color;
-}
-
-static inline void
-__rb_change_child(struct rb_node *old, struct rb_node *new,
-		  struct rb_node *parent, struct rb_root *root)
-{
-	if (parent) {
-		if (parent->rb_left == old)
-			parent->rb_left = new;
-		else
-			parent->rb_right = new;
-	} else
-		root->rb_node = new;
-}
-
-/*
- * Helper function for rotations:
- * - old's parent and color get assigned to new
- * - old gets assigned new as a parent and 'color' as a color.
- */
-static inline void
-__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
-			struct rb_root *root, int color)
-{
-	struct rb_node *parent = rb_parent(old);
-	new->__rb_parent_color = old->__rb_parent_color;
-	rb_set_parent_color(old, new, color);
-	__rb_change_child(old, new, parent, root);
-}
-
-void rb_insert_color(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
-
-	while (true) {
-		/*
-		 * Loop invariant: node is red
-		 *
-		 * If there is a black parent, we are done.
-		 * Otherwise, take some corrective action as we don't
-		 * want a red root or two consecutive red nodes.
-		 */
-		if (!parent) {
-			rb_set_parent_color(node, NULL, RB_BLACK);
-			break;
-		} else if (rb_is_black(parent))
-			break;
-
-		gparent = rb_red_parent(parent);
-
-		tmp = gparent->rb_right;
-		if (parent != tmp) {    /* parent == gparent->rb_left */
-			if (tmp && rb_is_red(tmp)) {
-				/*
-				 * Case 1 - color flips
-				 *
-				 *       G            g
-				 *      / \          / \
-				 *     p   u  -->   P   U
-				 *    /            /
-				 *   n            n
-				 *
-				 * However, since g's parent might be red, and
-				 * 4) does not allow this, we need to recurse
-				 * at g.
-				 */
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-				rb_set_parent_color(parent, gparent, RB_BLACK);
-				node = gparent;
-				parent = rb_parent(node);
-				rb_set_parent_color(node, parent, RB_RED);
-				continue;
-			}
-
-			tmp = parent->rb_right;
-			if (node == tmp) {
-				/*
-				 * Case 2 - left rotate at parent
-				 *
-				 *      G             G
-				 *     / \           / \
-				 *    p   U  -->    n   U
-				 *     \           /
-				 *      n         p
-				 *
-				 * This still leaves us in violation of 4), the
-				 * continuation into Case 3 will fix that.
-				 */
-				parent->rb_right = tmp = node->rb_left;
-				node->rb_left = parent;
-				if (tmp)
-					rb_set_parent_color(tmp, parent,
-							    RB_BLACK);
-				rb_set_parent_color(parent, node, RB_RED);
-				parent = node;
-				tmp = node->rb_right;
-			}
-
-			/*
-			 * Case 3 - right rotate at gparent
-			 *
-			 *        G           P
-			 *       / \         / \
-			 *      p   U  -->  n   g
-			 *     /                 \
-			 *    n                   U
-			 */
-			gparent->rb_left = tmp;  /* == parent->rb_right */
-			parent->rb_right = gparent;
-			if (tmp)
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
-			break;
-		} else {
-			tmp = gparent->rb_left;
-			if (tmp && rb_is_red(tmp)) {
-				/* Case 1 - color flips */
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-				rb_set_parent_color(parent, gparent, RB_BLACK);
-				node = gparent;
-				parent = rb_parent(node);
-				rb_set_parent_color(node, parent, RB_RED);
-				continue;
-			}
-
-			tmp = parent->rb_left;
-			if (node == tmp) {
-				/* Case 2 - right rotate at parent */
-				parent->rb_left = tmp = node->rb_right;
-				node->rb_right = parent;
-				if (tmp)
-					rb_set_parent_color(tmp, parent,
-							    RB_BLACK);
-				rb_set_parent_color(parent, node, RB_RED);
-				parent = node;
-				tmp = node->rb_left;
-			}
-
-			/* Case 3 - left rotate at gparent */
-			gparent->rb_right = tmp;  /* == parent->rb_left */
-			parent->rb_left = gparent;
-			if (tmp)
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
-			break;
-		}
-	}
-}
-EXPORT_SYMBOL(rb_insert_color);
-
-static void __rb_erase_color(struct rb_node *parent, struct rb_root *root)
-{
-	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
-
-	while (true) {
-		/*
-		 * Loop invariants:
-		 * - node is black (or NULL on first iteration)
-		 * - node is not the root (parent is not NULL)
-		 * - All leaf paths going through parent and node have a
-		 *   black node count that is 1 lower than other leaf paths.
-		 */
-		sibling = parent->rb_right;
-		if (node != sibling) {  /* node == parent->rb_left */
-			if (rb_is_red(sibling)) {
-				/*
-				 * Case 1 - left rotate at parent
-				 *
-				 *     P               S
-				 *    / \             / \
-				 *   N   s    -->    p   Sr
-				 *      / \         / \
-				 *     Sl  Sr      N   Sl
-				 */
-				parent->rb_right = tmp1 = sibling->rb_left;
-				sibling->rb_left = parent;
-				rb_set_parent_color(tmp1, parent, RB_BLACK);
-				__rb_rotate_set_parents(parent, sibling, root,
-							RB_RED);
-				sibling = tmp1;
-			}
-			tmp1 = sibling->rb_right;
-			if (!tmp1 || rb_is_black(tmp1)) {
-				tmp2 = sibling->rb_left;
-				if (!tmp2 || rb_is_black(tmp2)) {
-					/*
-					* Case 2 - sibling color flip
-					* (p could be either color here)
-					*
-					*    (p)           (p)
-					*    / \           / \
-					*   N   S    -->  N   s
-					*      / \           / \
-					*     Sl  Sr        Sl  Sr
-					*
-					* This leaves us violating 5) which
-					* can be fixed by flipping p to black
-					* if it was red, or by recursing at p.
-					* p is red when coming from Case 1.
-					*/
-					rb_set_parent_color(sibling, parent,
-							    RB_RED);
-					if (rb_is_red(parent))
-						rb_set_black(parent);
-					else {
-						node = parent;
-						parent = rb_parent(node);
-						if (parent)
-							continue;
-					}
-					break;
-				}
-				/*
-				 * Case 3 - right rotate at sibling
-				 * (p could be either color here)
-				 *
-				 *   (p)           (p)
-				 *   / \           / \
-				 *  N   S    -->  N   Sl
-				 *     / \             \
-				 *    sl  Sr            s
-				 *                       \
-				 *                        Sr
-				 */
-				sibling->rb_left = tmp1 = tmp2->rb_right;
-				tmp2->rb_right = sibling;
-				parent->rb_right = tmp2;
-				if (tmp1)
-					rb_set_parent_color(tmp1, sibling,
-							    RB_BLACK);
-				tmp1 = sibling;
-				sibling = tmp2;
-			}
-			/*
-			 * Case 4 - left rotate at parent + color flips
-			 * (p and sl could be either color here.
-			 *  After rotation, p becomes black, s acquires
-			 *  p's color, and sl keeps its color)
-			 *
-			 *      (p)             (s)
-			 *      / \             / \
-			 *     N   S     -->   P   Sr
-			 *        / \         / \
-			 *      (sl) sr      N  (sl)
-			 */
-			parent->rb_right = tmp2 = sibling->rb_left;
-			sibling->rb_left = parent;
-			rb_set_parent_color(tmp1, sibling, RB_BLACK);
-			if (tmp2)
-				rb_set_parent(tmp2, parent);
-			__rb_rotate_set_parents(parent, sibling, root,
-						RB_BLACK);
-			break;
-		} else {
-			sibling = parent->rb_left;
-			if (rb_is_red(sibling)) {
-				/* Case 1 - right rotate at parent */
-				parent->rb_left = tmp1 = sibling->rb_right;
-				sibling->rb_right = parent;
-				rb_set_parent_color(tmp1, parent, RB_BLACK);
-				__rb_rotate_set_parents(parent, sibling, root,
-							RB_RED);
-				sibling = tmp1;
-			}
-			tmp1 = sibling->rb_left;
-			if (!tmp1 || rb_is_black(tmp1)) {
-				tmp2 = sibling->rb_right;
-				if (!tmp2 || rb_is_black(tmp2)) {
-					/* Case 2 - sibling color flip */
-					rb_set_parent_color(sibling, parent,
-							    RB_RED);
-					if (rb_is_red(parent))
-						rb_set_black(parent);
-					else {
-						node = parent;
-						parent = rb_parent(node);
-						if (parent)
-							continue;
-					}
-					break;
-				}
-				/* Case 3 - right rotate at sibling */
-				sibling->rb_right = tmp1 = tmp2->rb_left;
-				tmp2->rb_left = sibling;
-				parent->rb_left = tmp2;
-				if (tmp1)
-					rb_set_parent_color(tmp1, sibling,
-							    RB_BLACK);
-				tmp1 = sibling;
-				sibling = tmp2;
-			}
-			/* Case 4 - left rotate at parent + color flips */
-			parent->rb_left = tmp2 = sibling->rb_right;
-			sibling->rb_right = parent;
-			rb_set_parent_color(tmp1, sibling, RB_BLACK);
-			if (tmp2)
-				rb_set_parent(tmp2, parent);
-			__rb_rotate_set_parents(parent, sibling, root,
-						RB_BLACK);
-			break;
-		}
-	}
-}
-
-void rb_erase(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
-	struct rb_node *parent, *rebalance;
-	unsigned long pc;
-
-	if (!tmp) {
-		/*
-		 * Case 1: node to erase has no more than 1 child (easy!)
-		 *
-		 * Note that if there is one child it must be red due to 5)
-		 * and node must be black due to 4). We adjust colors locally
-		 * so as to bypass __rb_erase_color() later on.
-		 */
-		pc = node->__rb_parent_color;
-		parent = __rb_parent(pc);
-		__rb_change_child(node, child, parent, root);
-		if (child) {
-			child->__rb_parent_color = pc;
-			rebalance = NULL;
-		} else
-			rebalance = __rb_is_black(pc) ? parent : NULL;
-	} else if (!child) {
-		/* Still case 1, but this time the child is node->rb_left */
-		tmp->__rb_parent_color = pc = node->__rb_parent_color;
-		parent = __rb_parent(pc);
-		__rb_change_child(node, tmp, parent, root);
-		rebalance = NULL;
-	} else {
-		struct rb_node *successor = child, *child2;
-		tmp = child->rb_left;
-		if (!tmp) {
-			/*
-			 * Case 2: node's successor is its right child
-			 *
-			 *    (n)          (s)
-			 *    / \          / \
-			 *  (x) (s)  ->  (x) (c)
-			 *        \
-			 *        (c)
-			 */
-			parent = child;
-			child2 = child->rb_right;
-		} else {
-			/*
-			 * Case 3: node's successor is leftmost under
-			 * node's right child subtree
-			 *
-			 *    (n)          (s)
-			 *    / \          / \
-			 *  (x) (y)  ->  (x) (y)
-			 *      /            /
-			 *    (p)          (p)
-			 *    /            /
-			 *  (s)          (c)
-			 *    \
-			 *    (c)
-			 */
-			do {
-				parent = successor;
-				successor = tmp;
-				tmp = tmp->rb_left;
-			} while (tmp);
-			parent->rb_left = child2 = successor->rb_right;
-			successor->rb_right = child;
-			rb_set_parent(child, successor);
-		}
-
-		successor->rb_left = tmp = node->rb_left;
-		rb_set_parent(tmp, successor);
-
-		pc = node->__rb_parent_color;
-		tmp = __rb_parent(pc);
-		__rb_change_child(node, successor, tmp, root);
-		if (child2) {
-			successor->__rb_parent_color = pc;
-			rb_set_parent_color(child2, parent, RB_BLACK);
-			rebalance = NULL;
-		} else {
-			unsigned long pc2 = successor->__rb_parent_color;
-			successor->__rb_parent_color = pc;
-			rebalance = __rb_is_black(pc2) ? parent : NULL;
-		}
-	}
-
-	if (rebalance)
-		__rb_erase_color(rebalance, root);
-}
-EXPORT_SYMBOL(rb_erase);
-
-/*
- * This function returns the first node (in sort order) of the tree.
- */
-struct rb_node *rb_first(const struct rb_root *root)
-{
-	struct rb_node	*n;
-
-	n = root->rb_node;
-	if (!n)
-		return NULL;
-	while (n->rb_left)
-		n = n->rb_left;
-	return n;
-}
-EXPORT_SYMBOL(rb_first);
-
-struct rb_node *rb_last(const struct rb_root *root)
-{
-	struct rb_node	*n;
-
-	n = root->rb_node;
-	if (!n)
-		return NULL;
-	while (n->rb_right)
-		n = n->rb_right;
-	return n;
-}
-EXPORT_SYMBOL(rb_last);
-
-struct rb_node *rb_next(const struct rb_node *node)
-{
-	struct rb_node *parent;
-
-	if (RB_EMPTY_NODE(node))
-		return NULL;
-
-	/*
-	 * If we have a right-hand child, go down and then left as far
-	 * as we can.
-	 */
-	if (node->rb_right) {
-		node = node->rb_right;
-		while (node->rb_left)
-			node=node->rb_left;
-		return (struct rb_node *)node;
-	}
-
-	/*
-	 * No right-hand children. Everything down and left is smaller than us,
-	 * so any 'next' node must be in the general direction of our parent.
-	 * Go up the tree; any time the ancestor is a right-hand child of its
-	 * parent, keep going up. First time it's a left-hand child of its
-	 * parent, said parent is our 'next' node.
-	 */
-	while ((parent = rb_parent(node)) && node == parent->rb_right)
-		node = parent;
-
-	return parent;
-}
-EXPORT_SYMBOL(rb_next);
-
-struct rb_node *rb_prev(const struct rb_node *node)
-{
-	struct rb_node *parent;
-
-	if (RB_EMPTY_NODE(node))
-		return NULL;
-
-	/*
-	 * If we have a left-hand child, go down and then right as far
-	 * as we can.
-	 */
-	if (node->rb_left) {
-		node = node->rb_left;
-		while (node->rb_right)
-			node=node->rb_right;
-		return (struct rb_node *)node;
-	}
-
-	/*
-	 * No left-hand children. Go up till we find an ancestor which
-	 * is a right-hand child of its parent
-	 */
-	while ((parent = rb_parent(node)) && node == parent->rb_left)
-		node = parent;
-
-	return parent;
-}
-EXPORT_SYMBOL(rb_prev);
-
-void rb_replace_node(struct rb_node *victim, struct rb_node *new,
-		     struct rb_root *root)
-{
-	struct rb_node *parent = rb_parent(victim);
-
-	/* Set the surrounding nodes to point to the replacement */
-	__rb_change_child(victim, new, parent, root);
-	if (victim->rb_left)
-		rb_set_parent(victim->rb_left, new);
-	if (victim->rb_right)
-		rb_set_parent(victim->rb_right, new);
-
-	/* Copy the pointers/colour from the victim to the replacement */
-	*new = *victim;
-}
-EXPORT_SYMBOL(rb_replace_node);
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 72c72fffec..b0fe8c72ac 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -4,3 +4,4 @@ lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
+lib-y += rbtree.o
diff --git a/xen/lib/rbtree.c b/xen/lib/rbtree.c
new file mode 100644
index 0000000000..95e045d524
--- /dev/null
+++ b/xen/lib/rbtree.c
@@ -0,0 +1,570 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  (C) 2002  David Woodhouse <dwmw2@infradead.org>
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/lib/rbtree.c
+*/
+
+#include <xen/types.h>
+#include <xen/rbtree.h>
+
+/*
+ * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
+ *
+ *  1) A node is either red or black
+ *  2) The root is black
+ *  3) All leaves (NULL) are black
+ *  4) Both children of every red node are black
+ *  5) Every simple path from root to leaves contains the same number
+ *     of black nodes.
+ *
+ *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
+ *  consecutive red nodes in a path and every red node is therefore followed by
+ *  a black. So if B is the number of black nodes on every simple path (as per
+ *  5), then the longest possible path due to 4 is 2B.
+ *
+ *  We shall indicate color with case, where black nodes are uppercase and red
+ *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
+ *  parentheses and have some accompanying text comment.
+ */
+
+#define		RB_RED		0
+#define		RB_BLACK	1
+
+#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc)     ((pc) & 1)
+#define __rb_is_black(pc)  __rb_color(pc)
+#define __rb_is_red(pc)    (!__rb_color(pc))
+#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
+
+static inline void rb_set_black(struct rb_node *rb)
+{
+	rb->__rb_parent_color |= RB_BLACK;
+}
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+
+static inline void rb_set_parent_color(struct rb_node *rb,
+				      struct rb_node *p, int color)
+{
+	rb->__rb_parent_color = (unsigned long)p | color;
+}
+
+static inline struct rb_node *rb_red_parent(struct rb_node *red)
+{
+	return (struct rb_node *)red->__rb_parent_color;
+}
+
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+		  struct rb_node *parent, struct rb_root *root)
+{
+	if (parent) {
+		if (parent->rb_left == old)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else
+		root->rb_node = new;
+}
+
+/*
+ * Helper function for rotations:
+ * - old's parent and color get assigned to new
+ * - old gets assigned new as a parent and 'color' as a color.
+ */
+static inline void
+__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
+			struct rb_root *root, int color)
+{
+	struct rb_node *parent = rb_parent(old);
+	new->__rb_parent_color = old->__rb_parent_color;
+	rb_set_parent_color(old, new, color);
+	__rb_change_child(old, new, parent, root);
+}
+
+void rb_insert_color(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
+
+	while (true) {
+		/*
+		 * Loop invariant: node is red
+		 *
+		 * If there is a black parent, we are done.
+		 * Otherwise, take some corrective action as we don't
+		 * want a red root or two consecutive red nodes.
+		 */
+		if (!parent) {
+			rb_set_parent_color(node, NULL, RB_BLACK);
+			break;
+		} else if (rb_is_black(parent))
+			break;
+
+		gparent = rb_red_parent(parent);
+
+		tmp = gparent->rb_right;
+		if (parent != tmp) {    /* parent == gparent->rb_left */
+			if (tmp && rb_is_red(tmp)) {
+				/*
+				 * Case 1 - color flips
+				 *
+				 *       G            g
+				 *      / \          / \
+				 *     p   u  -->   P   U
+				 *    /            /
+				 *   n            n
+				 *
+				 * However, since g's parent might be red, and
+				 * 4) does not allow this, we need to recurse
+				 * at g.
+				 */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_right;
+			if (node == tmp) {
+				/*
+				 * Case 2 - left rotate at parent
+				 *
+				 *      G             G
+				 *     / \           / \
+				 *    p   U  -->    n   U
+				 *     \           /
+				 *      n         p
+				 *
+				 * This still leaves us in violation of 4), the
+				 * continuation into Case 3 will fix that.
+				 */
+				parent->rb_right = tmp = node->rb_left;
+				node->rb_left = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				parent = node;
+				tmp = node->rb_right;
+			}
+
+			/*
+			 * Case 3 - right rotate at gparent
+			 *
+			 *        G           P
+			 *       / \         / \
+			 *      p   U  -->  n   g
+			 *     /                 \
+			 *    n                   U
+			 */
+			gparent->rb_left = tmp;  /* == parent->rb_right */
+			parent->rb_right = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			break;
+		} else {
+			tmp = gparent->rb_left;
+			if (tmp && rb_is_red(tmp)) {
+				/* Case 1 - color flips */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_left;
+			if (node == tmp) {
+				/* Case 2 - right rotate at parent */
+				parent->rb_left = tmp = node->rb_right;
+				node->rb_right = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				parent = node;
+				tmp = node->rb_left;
+			}
+
+			/* Case 3 - left rotate at gparent */
+			gparent->rb_right = tmp;  /* == parent->rb_left */
+			parent->rb_left = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			break;
+		}
+	}
+}
+
+static void __rb_erase_color(struct rb_node *parent, struct rb_root *root)
+{
+	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
+
+	while (true) {
+		/*
+		 * Loop invariants:
+		 * - node is black (or NULL on first iteration)
+		 * - node is not the root (parent is not NULL)
+		 * - All leaf paths going through parent and node have a
+		 *   black node count that is 1 lower than other leaf paths.
+		 */
+		sibling = parent->rb_right;
+		if (node != sibling) {  /* node == parent->rb_left */
+			if (rb_is_red(sibling)) {
+				/*
+				 * Case 1 - left rotate at parent
+				 *
+				 *     P               S
+				 *    / \             / \
+				 *   N   s    -->    p   Sr
+				 *      / \         / \
+				 *     Sl  Sr      N   Sl
+				 */
+				parent->rb_right = tmp1 = sibling->rb_left;
+				sibling->rb_left = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_right;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_left;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/*
+					* Case 2 - sibling color flip
+					* (p could be either color here)
+					*
+					*    (p)           (p)
+					*    / \           / \
+					*   N   S    -->  N   s
+					*      / \           / \
+					*     Sl  Sr        Sl  Sr
+					*
+					* This leaves us violating 5) which
+					* can be fixed by flipping p to black
+					* if it was red, or by recursing at p.
+					* p is red when coming from Case 1.
+					*/
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/*
+				 * Case 3 - right rotate at sibling
+				 * (p could be either color here)
+				 *
+				 *   (p)           (p)
+				 *   / \           / \
+				 *  N   S    -->  N   Sl
+				 *     / \             \
+				 *    sl  Sr            s
+				 *                       \
+				 *                        Sr
+				 */
+				sibling->rb_left = tmp1 = tmp2->rb_right;
+				tmp2->rb_right = sibling;
+				parent->rb_right = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/*
+			 * Case 4 - left rotate at parent + color flips
+			 * (p and sl could be either color here.
+			 *  After rotation, p becomes black, s acquires
+			 *  p's color, and sl keeps its color)
+			 *
+			 *      (p)             (s)
+			 *      / \             / \
+			 *     N   S     -->   P   Sr
+			 *        / \         / \
+			 *      (sl) sr      N  (sl)
+			 */
+			parent->rb_right = tmp2 = sibling->rb_left;
+			sibling->rb_left = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			break;
+		} else {
+			sibling = parent->rb_left;
+			if (rb_is_red(sibling)) {
+				/* Case 1 - right rotate at parent */
+				parent->rb_left = tmp1 = sibling->rb_right;
+				sibling->rb_right = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_left;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_right;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/* Case 2 - sibling color flip */
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/* Case 3 - right rotate at sibling */
+				sibling->rb_right = tmp1 = tmp2->rb_left;
+				tmp2->rb_left = sibling;
+				parent->rb_left = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/* Case 4 - left rotate at parent + color flips */
+			parent->rb_left = tmp2 = sibling->rb_right;
+			sibling->rb_right = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			break;
+		}
+	}
+}
+
+void rb_erase(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+	struct rb_node *parent, *rebalance;
+	unsigned long pc;
+
+	if (!tmp) {
+		/*
+		 * Case 1: node to erase has no more than 1 child (easy!)
+		 *
+		 * Note that if there is one child it must be red due to 5)
+		 * and node must be black due to 4). We adjust colors locally
+		 * so as to bypass __rb_erase_color() later on.
+		 */
+		pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, child, parent, root);
+		if (child) {
+			child->__rb_parent_color = pc;
+			rebalance = NULL;
+		} else
+			rebalance = __rb_is_black(pc) ? parent : NULL;
+	} else if (!child) {
+		/* Still case 1, but this time the child is node->rb_left */
+		tmp->__rb_parent_color = pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, tmp, parent, root);
+		rebalance = NULL;
+	} else {
+		struct rb_node *successor = child, *child2;
+		tmp = child->rb_left;
+		if (!tmp) {
+			/*
+			 * Case 2: node's successor is its right child
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (s)  ->  (x) (c)
+			 *        \
+			 *        (c)
+			 */
+			parent = child;
+			child2 = child->rb_right;
+		} else {
+			/*
+			 * Case 3: node's successor is leftmost under
+			 * node's right child subtree
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (y)  ->  (x) (y)
+			 *      /            /
+			 *    (p)          (p)
+			 *    /            /
+			 *  (s)          (c)
+			 *    \
+			 *    (c)
+			 */
+			do {
+				parent = successor;
+				successor = tmp;
+				tmp = tmp->rb_left;
+			} while (tmp);
+			parent->rb_left = child2 = successor->rb_right;
+			successor->rb_right = child;
+			rb_set_parent(child, successor);
+		}
+
+		successor->rb_left = tmp = node->rb_left;
+		rb_set_parent(tmp, successor);
+
+		pc = node->__rb_parent_color;
+		tmp = __rb_parent(pc);
+		__rb_change_child(node, successor, tmp, root);
+		if (child2) {
+			successor->__rb_parent_color = pc;
+			rb_set_parent_color(child2, parent, RB_BLACK);
+			rebalance = NULL;
+		} else {
+			unsigned long pc2 = successor->__rb_parent_color;
+			successor->__rb_parent_color = pc;
+			rebalance = __rb_is_black(pc2) ? parent : NULL;
+		}
+	}
+
+	if (rebalance)
+		__rb_erase_color(rebalance, root);
+}
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct rb_node *rb_first(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_left)
+		n = n->rb_left;
+	return n;
+}
+
+struct rb_node *rb_last(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_right)
+		n = n->rb_right;
+	return n;
+}
+
+struct rb_node *rb_next(const struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (RB_EMPTY_NODE(node))
+		return NULL;
+
+	/*
+	 * If we have a right-hand child, go down and then left as far
+	 * as we can.
+	 */
+	if (node->rb_right) {
+		node = node->rb_right;
+		while (node->rb_left)
+			node=node->rb_left;
+		return (struct rb_node *)node;
+	}
+
+	/*
+	 * No right-hand children. Everything down and left is smaller than us,
+	 * so any 'next' node must be in the general direction of our parent.
+	 * Go up the tree; any time the ancestor is a right-hand child of its
+	 * parent, keep going up. First time it's a left-hand child of its
+	 * parent, said parent is our 'next' node.
+	 */
+	while ((parent = rb_parent(node)) && node == parent->rb_right)
+		node = parent;
+
+	return parent;
+}
+
+struct rb_node *rb_prev(const struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (RB_EMPTY_NODE(node))
+		return NULL;
+
+	/*
+	 * If we have a left-hand child, go down and then right as far
+	 * as we can.
+	 */
+	if (node->rb_left) {
+		node = node->rb_left;
+		while (node->rb_right)
+			node=node->rb_right;
+		return (struct rb_node *)node;
+	}
+
+	/*
+	 * No left-hand children. Go up till we find an ancestor which
+	 * is a right-hand child of its parent
+	 */
+	while ((parent = rb_parent(node)) && node == parent->rb_left)
+		node = parent;
+
+	return parent;
+}
+
+void rb_replace_node(struct rb_node *victim, struct rb_node *new,
+		     struct rb_root *root)
+{
+	struct rb_node *parent = rb_parent(victim);
+
+	/* Set the surrounding nodes to point to the replacement */
+	__rb_change_child(victim, new, parent, root);
+	if (victim->rb_left)
+		rb_set_parent(victim->rb_left, new);
+	if (victim->rb_right)
+		rb_set_parent(victim->rb_right, new);
+
+	/* Copy the pointers/colour from the victim to the replacement */
+	*new = *victim;
+}
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:33:57 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:33:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56488.98908 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExJ-0000vJ-5Q; Fri, 18 Dec 2020 12:33:57 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56488.98908; Fri, 18 Dec 2020 12:33:57 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExJ-0000vC-2j; Fri, 18 Dec 2020 12:33:57 +0000
Received: by outflank-mailman (input) for mailman id 56488;
 Fri, 18 Dec 2020 12:33:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExH-0000v1-9l
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExH-0007BF-8v
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExH-0006yG-7k
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:33:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=VBBcbRvQZrFkmsXpuApyJOpa1LYmjowK9Oy6Pbe9k3s=; b=NUnSgUdkGN4buPggMss/STrdin
	PnhT0COC2/RHLm3YyNmYALXmdclpPwdm8HopkabORwi1WOTutJnzGLC/0vvIFJOSH60txs3mIRRVC
	wLJRxhZvC349x4RTpB8LKhCJLg/OiHWdK5eTD1jK/zN1CUZXgdNGhKiP6JbkF92nFk20=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move bsearch code
Message-Id: <E1kqExH-0006yG-7k@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:33:55 +0000

commit 7c3af561acb70ddd16069b9c9cab3ce503a10987
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:23:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:23:42 2020 +0100

    lib: move bsearch code
    
    Convert this code to an inline function (backed by an instance in an
    archive in case the compiler decides against inlining), which results
    in not having it in x86 final binaries. This saves a little bit of dead
    code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile        |  1 -
 xen/common/bsearch.c       | 51 ----------------------------------------------
 xen/include/xen/compiler.h |  1 +
 xen/include/xen/lib.h      | 42 +++++++++++++++++++++++++++++++++++++-
 xen/lib/Makefile           |  1 +
 xen/lib/bsearch.c          | 13 ++++++++++++
 6 files changed, 56 insertions(+), 53 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index d65c9fe9cb..e8ce23acea 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -1,6 +1,5 @@
 obj-$(CONFIG_ARGO) += argo.o
 obj-y += bitmap.o
-obj-y += bsearch.o
 obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
 obj-$(CONFIG_CORE_PARKING) += core_parking.o
 obj-y += cpu.o
diff --git a/xen/common/bsearch.c b/xen/common/bsearch.c
deleted file mode 100644
index 7090930aab..0000000000
--- a/xen/common/bsearch.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * A generic implementation of binary search for the Linux kernel
- *
- * Copyright (C) 2008-2009 Ksplice, Inc.
- * Author: Tim Abbott <tabbott@ksplice.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2.
- */
-
-#include <xen/lib.h>
-
-/*
- * bsearch - binary search an array of elements
- * @key: pointer to item being searched for
- * @base: pointer to first element to search
- * @num: number of elements
- * @size: size of each element
- * @cmp: pointer to comparison function
- *
- * This function does a binary search on the given array.  The
- * contents of the array should already be in ascending sorted order
- * under the provided comparison function.
- *
- * Note that the key need not have the same type as the elements in
- * the array, e.g. key could be a string and the comparison function
- * could compare the string with the struct's name field.  However, if
- * the key and elements in the array are of the same type, you can use
- * the same comparison function for both sort() and bsearch().
- */
-void *bsearch(const void *key, const void *base, size_t num, size_t size,
-	      int (*cmp)(const void *key, const void *elt))
-{
-	size_t start = 0, end = num;
-	int result;
-
-	while (start < end) {
-		size_t mid = start + (end - start) / 2;
-
-		result = cmp(key, base + mid * size);
-		if (result < 0)
-			end = mid;
-		else if (result > 0)
-			start = mid + 1;
-		else
-			return (void *)base + mid * size;
-	}
-
-	return NULL;
-}
diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h
index 676c6ea1b0..e643e69128 100644
--- a/xen/include/xen/compiler.h
+++ b/xen/include/xen/compiler.h
@@ -12,6 +12,7 @@
 
 #define inline        __inline__
 #define always_inline __inline__ __attribute__ ((__always_inline__))
+#define gnu_inline    __inline__ __attribute__ ((__gnu_inline__))
 #define noinline      __attribute__((__noinline__))
 
 #define noreturn      __attribute__((__noreturn__))
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index a9679c913d..48429b69b8 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -204,8 +204,48 @@ void dump_execstate(struct cpu_user_regs *);
 
 void init_constructors(void);
 
+/*
+ * bsearch - binary search an array of elements
+ * @key: pointer to item being searched for
+ * @base: pointer to first element to search
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp: pointer to comparison function
+ *
+ * This function does a binary search on the given array.  The
+ * contents of the array should already be in ascending sorted order
+ * under the provided comparison function.
+ *
+ * Note that the key need not have the same type as the elements in
+ * the array, e.g. key could be a string and the comparison function
+ * could compare the string with the struct's name field.  However, if
+ * the key and elements in the array are of the same type, you can use
+ * the same comparison function for both sort() and bsearch().
+ */
+#ifndef BSEARCH_IMPLEMENTATION
+extern gnu_inline
+#endif
 void *bsearch(const void *key, const void *base, size_t num, size_t size,
-              int (*cmp)(const void *key, const void *elt));
+              int (*cmp)(const void *key, const void *elt))
+{
+    size_t start = 0, end = num;
+    int result;
+
+    while ( start < end )
+    {
+        size_t mid = start + (end - start) / 2;
+
+        result = cmp(key, base + mid * size);
+        if ( result < 0 )
+            end = mid;
+        else if ( result > 0 )
+            start = mid + 1;
+        else
+            return (void *)base + mid * size;
+    }
+
+    return NULL;
+}
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index b0fe8c72ac..f12dab7a73 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_X86) += x86/
 
+lib-y += bsearch.o
 lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
diff --git a/xen/lib/bsearch.c b/xen/lib/bsearch.c
new file mode 100644
index 0000000000..149f7feafd
--- /dev/null
+++ b/xen/lib/bsearch.c
@@ -0,0 +1,13 @@
+/*
+ * A generic implementation of binary search for the Linux kernel
+ *
+ * Copyright (C) 2008-2009 Ksplice, Inc.
+ * Author: Tim Abbott <tabbott@ksplice.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2.
+ */
+
+#define BSEARCH_IMPLEMENTATION
+#include <xen/lib.h>
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:34:07 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:34:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56489.98912 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExT-0000wY-7A; Fri, 18 Dec 2020 12:34:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56489.98912; Fri, 18 Dec 2020 12:34:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExT-0000wQ-4I; Fri, 18 Dec 2020 12:34:07 +0000
Received: by outflank-mailman (input) for mailman id 56489;
 Fri, 18 Dec 2020 12:34:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExR-0000wD-Ck
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExR-0007Bd-Bz
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExR-0006zH-B1
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Z2Mz0UvsFkZY2wUidFxS433hr9RQltzOzpaQIByanXk=; b=aMS5dzNh/T2lqS+f8G1DiTxHBe
	iJm114cPJJnHB9lT/TkcasVJYbCxc+vNjfT4GLXTnzx+flN3Gf42f1qczgWNC1N2XQIDYzII+EewV
	lcDqq9rxzMJgP4wCypTyXE5aRTwK4xsmJGIvQIvC+GDmp9IYLfZHsPzDq8pY41bCSijE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] lib: move sort code
Message-Id: <E1kqExR-0006zH-B1@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:34:05 +0000

commit f772b592b75d3144174d4c645b916f2718d9cce5
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:25:40 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:25:40 2020 +0100

    lib: move sort code
    
    Build this code into an archive, partly paralleling bsearch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile |  1 -
 xen/common/sort.c   | 82 -----------------------------------------------------
 xen/lib/Makefile    |  1 +
 xen/lib/sort.c      | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 83 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index e8ce23acea..7a4e652b57 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -36,7 +36,6 @@ obj-y += rcupdate.o
 obj-y += rwlock.o
 obj-y += shutdown.o
 obj-y += softirq.o
-obj-y += sort.o
 obj-y += smp.o
 obj-y += spinlock.o
 obj-y += stop_machine.o
diff --git a/xen/common/sort.c b/xen/common/sort.c
deleted file mode 100644
index 7b7544bbc2..0000000000
--- a/xen/common/sort.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
- *
- * Jan 23 2005  Matt Mackall <mpm@selenic.com>
- */
-
-#include <xen/types.h>
-
-static void u32_swap(void *a, void *b, int size)
-{
-    u32 t = *(u32 *)a;
-    *(u32 *)a = *(u32 *)b;
-    *(u32 *)b = t;
-}
-
-static void generic_swap(void *a, void *b, int size)
-{
-    char t;
-
-    do {
-        t = *(char *)a;
-        *(char *)a++ = *(char *)b;
-        *(char *)b++ = t;
-    } while ( --size > 0 );
-}
-
-/*
- * sort - sort an array of elements
- * @base: pointer to data to sort
- * @num: number of elements
- * @size: size of each element
- * @cmp: pointer to comparison function
- * @swap: pointer to swap function or NULL
- *
- * This function does a heapsort on the given array. You may provide a
- * swap function optimized to your element type.
- *
- * Sorting time is O(n log n) both on average and worst-case. While
- * qsort is about 20% faster on average, it suffers from exploitable
- * O(n*n) worst-case behavior and extra memory requirements that make
- * it less suitable for kernel use.
- */
-
-void sort(void *base, size_t num, size_t size,
-          int (*cmp)(const void *, const void *),
-          void (*swap)(void *, void *, int size))
-{
-    /* pre-scale counters for performance */
-    int i = (num/2 - 1) * size, n = num * size, c, r;
-
-    if (!swap)
-        swap = (size == 4 ? u32_swap : generic_swap);
-
-    /* heapify */
-    for ( ; i >= 0; i -= size )
-    {
-        for ( r = i; r * 2 + size < n; r  = c )
-        {
-            c = r * 2 + size;
-            if ( (c < n - size) && (cmp(base + c, base + c + size) < 0) )
-                c += size;
-            if ( cmp(base + r, base + c) >= 0 )
-                break;
-            swap(base + r, base + c, size);
-        }
-    }
-
-    /* sort */
-    for ( i = n - size; i >= 0; i -= size )
-    {
-        swap(base, base + i, size);
-        for ( r = 0; r * 2 + size < i; r = c )
-        {
-            c = r * 2 + size;
-            if ( (c < i - size) && (cmp(base + c, base + c + size) < 0) )
-                c += size;
-            if ( cmp(base + r, base + c) >= 0 )
-                break;
-            swap(base + r, base + c, size);
-        }
-    }
-}
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index f12dab7a73..42cf7a1164 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -6,3 +6,4 @@ lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
 lib-y += rbtree.o
+lib-y += sort.o
diff --git a/xen/lib/sort.c b/xen/lib/sort.c
new file mode 100644
index 0000000000..ee983d0bc3
--- /dev/null
+++ b/xen/lib/sort.c
@@ -0,0 +1,82 @@
+/*
+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
+ *
+ * Jan 23 2005  Matt Mackall <mpm@selenic.com>
+ */
+
+#include <xen/types.h>
+
+static void u32_swap(void *a, void *b, int size)
+{
+    u32 t = *(u32 *)a;
+    *(u32 *)a = *(u32 *)b;
+    *(u32 *)b = t;
+}
+
+static void generic_swap(void *a, void *b, int size)
+{
+    char t;
+
+    do {
+        t = *(char *)a;
+        *(char *)a++ = *(char *)b;
+        *(char *)b++ = t;
+    } while ( --size > 0 );
+}
+
+/*
+ * sort - sort an array of elements
+ * @base: pointer to data to sort
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp: pointer to comparison function
+ * @swap: pointer to swap function or NULL
+ *
+ * This function does a heapsort on the given array. You may provide a
+ * swap function optimized to your element type.
+ *
+ * Sorting time is O(n log n) both on average and worst-case. While
+ * qsort is about 20% faster on average, it suffers from exploitable
+ * O(n*n) worst-case behavior and extra memory requirements that make
+ * it less suitable for kernel use.
+ */
+
+void sort(void *base, size_t num, size_t size,
+          int (*cmp)(const void *, const void *),
+          void (*swap)(void *, void *, int size))
+{
+    /* pre-scale counters for performance */
+    int i = (num / 2 - 1) * size, n = num * size, c, r;
+
+    if ( !swap )
+        swap = (size == 4 ? u32_swap : generic_swap);
+
+    /* heapify */
+    for ( ; i >= 0; i -= size )
+    {
+        for ( r = i; r * 2 + size < n; r  = c )
+        {
+            c = r * 2 + size;
+            if ( (c < n - size) && (cmp(base + c, base + c + size) < 0) )
+                c += size;
+            if ( cmp(base + r, base + c) >= 0 )
+                break;
+            swap(base + r, base + c, size);
+        }
+    }
+
+    /* sort */
+    for ( i = n - size; i >= 0; i -= size )
+    {
+        swap(base, base + i, size);
+        for ( r = 0; r * 2 + size < i; r = c )
+        {
+            c = r * 2 + size;
+            if ( (c < i - size) && (cmp(base + c, base + c + size) < 0) )
+                c += size;
+            if ( cmp(base + r, base + c) >= 0 )
+                break;
+            swap(base + r, base + c, size);
+        }
+    }
+}
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:34:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:34:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56490.98916 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExd-0000y5-8u; Fri, 18 Dec 2020 12:34:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56490.98916; Fri, 18 Dec 2020 12:34:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExd-0000xw-60; Fri, 18 Dec 2020 12:34:17 +0000
Received: by outflank-mailman (input) for mailman id 56490;
 Fri, 18 Dec 2020 12:34:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExb-0000xq-GI
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExb-0007C2-FZ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExb-00070Z-E1
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=VhsX0MH+YoRKz4NflF+6z2D1eWrdW4Mi7kK/VVKzu9U=; b=i2eQ+5vgjzdah2N3PV6lR3DfrM
	bJhD0HudyJHcYklJ7mRtz50Ql9VVa8hA3NQA/gOJcx0fxQfJrnh/SqftHrwl2pOfOtezJdAmslktm
	+AR2v2YhmxTYtuxSiSn1N4K0L21+u4CSXCRj4tqlvSn8PGqMVGiA9OJbJbOebEFts1HA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/p2m: tidy p2m_add_foreign() a little
Message-Id: <E1kqExb-00070Z-E1@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:34:15 +0000

commit 173ae325026bd161ae5eecebda28dab2c7a80668
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:28:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:28:30 2020 +0100

    x86/p2m: tidy p2m_add_foreign() a little
    
    Drop a bogus ASSERT() - we don't typically assert incoming domain
    pointers to be non-NULL, and there's no particular reason to do so here.
    
    Replace the open-coded DOMID_SELF check by use of
    rcu_lock_remote_domain_by_id(), at the same time covering the request
    being made with the current domain's actual ID.
    
    Move the "both domains same" check into just the path where it really
    is meaningful.
    
    Swap the order of the two puts, such that
    - the p2m lock isn't needlessly held across put_page(),
    - a separate put_page() on an error path can be avoided,
    - they're inverse to the order of the respective gets.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm/p2m.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index cd0812db18..4caa666def 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -2565,9 +2565,6 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     int rc;
     struct domain *fdom;
 
-    ASSERT(tdom);
-    if ( foreigndom == DOMID_SELF )
-        return -EINVAL;
     /*
      * hvm fixme: until support is added to p2m teardown code to cleanup any
      * foreign entries, limit this to hardware domain only.
@@ -2578,13 +2575,15 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     if ( foreigndom == DOMID_XEN )
         fdom = rcu_lock_domain(dom_xen);
     else
-        fdom = rcu_lock_domain_by_id(foreigndom);
-    if ( fdom == NULL )
-        return -ESRCH;
+    {
+        rc = rcu_lock_remote_domain_by_id(foreigndom, &fdom);
+        if ( rc )
+            return rc;
 
-    rc = -EINVAL;
-    if ( tdom == fdom )
-        goto out;
+        rc = -EINVAL;
+        if ( tdom == fdom )
+            goto out;
+    }
 
     rc = xsm_map_gmfn_foreign(XSM_TARGET, tdom, fdom);
     if ( rc )
@@ -2598,10 +2597,8 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     if ( !page ||
          !p2m_is_ram(p2mt) || p2m_is_shared(p2mt) || p2m_is_hole(p2mt) )
     {
-        if ( page )
-            put_page(page);
         rc = -EINVAL;
-        goto out;
+        goto put_one;
     }
     mfn = page_to_mfn(page);
 
@@ -2630,8 +2627,6 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
                  gpfn, mfn_x(mfn), fgfn, tdom->domain_id, fdom->domain_id);
 
  put_both:
-    put_page(page);
-
     /*
      * This put_gfn for the above get_gfn for prev_mfn.  We must do this
      * after set_foreign_p2m_entry so another cpu doesn't populate the gpfn
@@ -2639,9 +2634,13 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
      */
     put_gfn(tdom, gpfn);
 
-out:
+ put_one:
+    put_page(page);
+
+ out:
     if ( fdom )
         rcu_unlock_domain(fdom);
+
     return rc;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 12:34:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 12:34:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56491.98919 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExn-0000zU-AO; Fri, 18 Dec 2020 12:34:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56491.98919; Fri, 18 Dec 2020 12:34:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqExn-0000zM-7Y; Fri, 18 Dec 2020 12:34:27 +0000
Received: by outflank-mailman (input) for mailman id 56491;
 Fri, 18 Dec 2020 12:34:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExl-0000zE-KK
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExl-0007CC-JQ
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqExl-00071X-IC
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 12:34:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8Mbtb2etDQajVZzj9Etul9Zk6E/KFHtyS2GvY1gilww=; b=iDjUg+FQ9NETpOaGTLh+yg/PPT
	+PZUi9Y9AgvM0FiE24SCwHy/WcnR34ZfioKsoIuH6NDZyHLI8pyQQwcPLFK7P8SzV5AcxioWU+sGx
	p18rgJjcydR5qlI+LuMexHopiSpMtDGK5yd2cqxI7npk+dBPcQxtP0/4UuUFVMgPLoi8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/mm: p2m_add_foreign() is HVM-only
Message-Id: <E1kqExl-00071X-IC@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 12:34:25 +0000

commit 8009c33b5179536e2ecce54462fe4cd069060f77
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:29:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:29:14 2020 +0100

    x86/mm: p2m_add_foreign() is HVM-only
    
    This is the case also for xenmem_add_to_physmap_one(), as is it's only
    caller of the function. Move the latter next to p2m_add_foreign(),
    allowing it one to become static at the same time. While moving, adjust
    indentation of the body of the main switch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 -----------------------------------------
 xen/arch/x86/mm/p2m.c     | 124 ++++++++++++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/p2m.h |   4 --
 3 files changed, 120 insertions(+), 120 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 723cc1070f..79acf20c4e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,7 +118,6 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
-#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -142,10 +141,7 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
-
-#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
-#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4591,114 +4587,6 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-        case XENMAPSPACE_shared_info:
-            if ( idx == 0 )
-                mfn = virt_to_mfn(d->shared_info);
-            break;
-        case XENMAPSPACE_grant_table:
-            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-            if ( rc )
-                return rc;
-            break;
-        case XENMAPSPACE_gmfn:
-        {
-            p2m_type_t p2mt;
-
-            gfn = idx;
-            mfn = get_gfn_unshare(d, gfn, &p2mt);
-            /* If the page is still shared, exit early */
-            if ( p2m_is_shared(p2mt) )
-            {
-                put_gfn(d, gfn);
-                return -ENOMEM;
-            }
-            page = get_page_from_mfn(mfn, d);
-            if ( unlikely(!page) )
-                mfn = INVALID_MFN;
-            break;
-        }
-        case XENMAPSPACE_gmfn_foreign:
-            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-        default:
-            break;
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4caa666def..487959b121 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,6 +27,7 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
+#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -42,6 +43,10 @@
 
 #include "mm-locks.h"
 
+/* Override macro from asm/page.h to make work with mfn_t */
+#undef virt_to_mfn
+#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
+
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2540,6 +2545,8 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
+#ifdef CONFIG_HVM
+
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2556,8 +2563,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreigndom)
+static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                           unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2644,7 +2651,115 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-#ifdef CONFIG_HVM
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+    case XENMAPSPACE_shared_info:
+        if ( idx == 0 )
+            mfn = virt_to_mfn(d->shared_info);
+        break;
+
+    case XENMAPSPACE_grant_table:
+        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+        if ( rc )
+            return rc;
+        break;
+
+    case XENMAPSPACE_gmfn:
+    {
+        p2m_type_t p2mt;
+
+        gfn = idx;
+        mfn = get_gfn_unshare(d, gfn, &p2mt);
+        /* If the page is still shared, exit early */
+        if ( p2m_is_shared(p2mt) )
+        {
+            put_gfn(d, gfn);
+            return -ENOMEM;
+        }
+        page = get_page_from_mfn(mfn, d);
+        if ( unlikely(!page) )
+            mfn = INVALID_MFN;
+        break;
+    }
+
+    case XENMAPSPACE_gmfn_foreign:
+        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2797,7 +2912,8 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-#endif
+
+#endif /* CONFIG_HVM */
 
 /*
  * Local variables:
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 8d6fd1aa01..6447696bcd 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,10 +661,6 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
-/* Add foreign mapping to the guest's p2m table. */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreign_domid);
-
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 17:55:12 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 17:55:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56592.99139 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqJy5-0000bP-KI; Fri, 18 Dec 2020 17:55:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56592.99139; Fri, 18 Dec 2020 17:55:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqJy5-0000bH-HG; Fri, 18 Dec 2020 17:55:05 +0000
Received: by outflank-mailman (input) for mailman id 56592;
 Fri, 18 Dec 2020 17:55:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqJy4-0000bA-Cu
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 17:55:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqJy4-0004ea-8y
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 17:55:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqJy4-00013f-6f
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 17:55:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gc1hrjRNomO1s1YAhlsGwdcrGf5QcNYnrOoWv0AjjPs=; b=1nroYGynT8yb4C5ML3SI+SzDaG
	be6gAChkYg0VSCu5hVfdGOXMTVxXRCPpmAK79demWWdg4oDDLBuSKbfsKK2zmFsTrIX5NFTky0eO5
	D40Fxrvf6KiSzoCFmL96MaTLAyBWiarefkDGhBZAVZCRATZT+wVtT/4iJkdfsYWKbXUI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] Revert "x86/mm: p2m_add_foreign() is HVM-only"
Message-Id: <E1kqJy4-00013f-6f@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 17:55:04 +0000

commit 357db96a66e47e609c3b14768f1062e13eedbd93
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Fri Dec 18 17:53:13 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Fri Dec 18 17:53:13 2020 +0000

    Revert "x86/mm: p2m_add_foreign() is HVM-only"
    
    This reverts commit 8009c33b5179536e2ecce54462fe4cd069060f77.  It breaks the
    PV-Shim build.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 +++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/p2m.c     | 124 ++--------------------------------------------
 xen/include/asm-x86/p2m.h |   4 ++
 3 files changed, 120 insertions(+), 120 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 79acf20c4e..723cc1070f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,6 +118,7 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
+#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -141,7 +142,10 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
+
+#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
+#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4587,6 +4591,114 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+        case XENMAPSPACE_shared_info:
+            if ( idx == 0 )
+                mfn = virt_to_mfn(d->shared_info);
+            break;
+        case XENMAPSPACE_grant_table:
+            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+            if ( rc )
+                return rc;
+            break;
+        case XENMAPSPACE_gmfn:
+        {
+            p2m_type_t p2mt;
+
+            gfn = idx;
+            mfn = get_gfn_unshare(d, gfn, &p2mt);
+            /* If the page is still shared, exit early */
+            if ( p2m_is_shared(p2mt) )
+            {
+                put_gfn(d, gfn);
+                return -ENOMEM;
+            }
+            page = get_page_from_mfn(mfn, d);
+            if ( unlikely(!page) )
+                mfn = INVALID_MFN;
+            break;
+        }
+        case XENMAPSPACE_gmfn_foreign:
+            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+        default:
+            break;
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 487959b121..4caa666def 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,7 +27,6 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
-#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -43,10 +42,6 @@
 
 #include "mm-locks.h"
 
-/* Override macro from asm/page.h to make work with mfn_t */
-#undef virt_to_mfn
-#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
-
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2545,8 +2540,6 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
-#ifdef CONFIG_HVM
-
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2563,8 +2556,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                           unsigned long gpfn, domid_t foreigndom)
+int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                    unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2651,115 +2644,7 @@ static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-    case XENMAPSPACE_shared_info:
-        if ( idx == 0 )
-            mfn = virt_to_mfn(d->shared_info);
-        break;
-
-    case XENMAPSPACE_grant_table:
-        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-        if ( rc )
-            return rc;
-        break;
-
-    case XENMAPSPACE_gmfn:
-    {
-        p2m_type_t p2mt;
-
-        gfn = idx;
-        mfn = get_gfn_unshare(d, gfn, &p2mt);
-        /* If the page is still shared, exit early */
-        if ( p2m_is_shared(p2mt) )
-        {
-            put_gfn(d, gfn);
-            return -ENOMEM;
-        }
-        page = get_page_from_mfn(mfn, d);
-        if ( unlikely(!page) )
-            mfn = INVALID_MFN;
-        break;
-    }
-
-    case XENMAPSPACE_gmfn_foreign:
-        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
+#ifdef CONFIG_HVM
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2912,8 +2797,7 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-
-#endif /* CONFIG_HVM */
+#endif
 
 /*
  * Local variables:
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 6447696bcd..8d6fd1aa01 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,6 +661,10 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
+/* Add foreign mapping to the guest's p2m table. */
+int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                    unsigned long gpfn, domid_t foreign_domid);
+
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56739.99416 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOTj-0005T5-KM; Fri, 18 Dec 2020 22:44:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56739.99416; Fri, 18 Dec 2020 22:44:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOTj-0005Sx-HN; Fri, 18 Dec 2020 22:44:03 +0000
Received: by outflank-mailman (input) for mailman id 56739;
 Fri, 18 Dec 2020 22:44:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTi-0005Ss-24
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTh-00017O-VS
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:01 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTh-0007qA-TV
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:01 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=j6BxYfT/X5bgmgbT7xHFIr3S39Gx6twvgMvEPUDaPjI=; b=bk7SOiDBYvRRItAp2/SX7qLMle
	ShKnavme6BFRGhggjR+kbOs5B5+c5Rjec3GRUGyLAmU3y609vbfSsZZXPtejUWWfBUBsuByYKSLDc
	Z/sgmb5ux4SMI/Px+v0+OQnQbC1JCHZmV5shpaEGFHuOsZ9Te8exAAe34g6UVxA0G2TU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/arm: Add workaround for Cortex-A53 erratum #843419
Message-Id: <E1kqOTh-0007qA-TV@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:01 +0000

commit d81133d45d81d35a4e7445778bfd1179190cbd31
Author:     Luca Fancellu <luca.fancellu@arm.com>
AuthorDate: Thu Dec 10 10:42:58 2020 +0000
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Wed Dec 16 17:56:33 2020 -0800

    xen/arm: Add workaround for Cortex-A53 erratum #843419
    
    On the Cortex A53, when executing in AArch64 state, a load or store instruction
    which uses the result of an ADRP instruction as a base register, or which uses
    a base register written by an instruction immediately after an ADRP to the
    same register, might access an incorrect address.
    
    The workaround is to enable the linker flag --fix-cortex-a53-843419
    if present, to check and fix the affected sequence. Otherwise print a warning
    that Xen may be susceptible to this errata
    
    Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
---
 docs/misc/arm/silicon-errata.txt |  1 +
 xen/arch/arm/Kconfig             | 19 +++++++++++++++++++
 xen/arch/arm/Makefile            |  8 ++++++++
 xen/scripts/Kbuild.include       | 12 ++++++++++++
 4 files changed, 40 insertions(+)

diff --git a/docs/misc/arm/silicon-errata.txt b/docs/misc/arm/silicon-errata.txt
index 27bf957ebf..1925d8fd4e 100644
--- a/docs/misc/arm/silicon-errata.txt
+++ b/docs/misc/arm/silicon-errata.txt
@@ -45,6 +45,7 @@ stable hypervisors.
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319    |
 | ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069    |
 | ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472    |
+| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419    |
 | ARM            | Cortex-A55      | #1530923        | N/A                     |
 | ARM            | Cortex-A57      | #852523         | N/A                     |
 | ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075    |
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index f5b1bcda03..41bde2f401 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -186,6 +186,25 @@ config ARM64_ERRATUM_819472
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_843419
+	bool "Cortex-A53: 843419: A load or store might access an incorrect address"
+	default y
+	depends on ARM_64
+	help
+	  This option adds an alternative code sequence to work around ARM
+	  erratum 843419 on Cortex-A53 parts up to r0p4.
+
+	  When executing in AArch64 state, a load or store instruction which uses
+	  the result of an ADRP instruction as a base register, or which uses a
+	  base register written by an instruction immediately after an ADRP to the
+	  same register, might access an incorrect address.
+
+	  The workaround enables the linker to check if the affected sequence is
+	  produced and it will fix it with an alternative not affected sequence
+	  that produce the same behavior.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_832075
 	bool "Cortex-A57: 832075: possible deadlock on mixing exclusive memory accesses with device loads"
 	default y
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 296c5e68bb..ad2d497c45 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -101,6 +101,14 @@ prelink.o: $(ALL_OBJS) FORCE
 	$(call if_changed,ld)
 endif
 
+ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
+    ifeq ($(call ld-option, --fix-cortex-a53-843419),n)
+        $(warning ld does not support --fix-cortex-a53-843419; xen may be susceptible to erratum)
+    else
+        XEN_LDFLAGS += --fix-cortex-a53-843419
+    endif
+endif
+
 targets += prelink.o
 
 $(TARGET)-syms: prelink.o xen.lds
diff --git a/xen/scripts/Kbuild.include b/xen/scripts/Kbuild.include
index e62eddc365..83c7e1457b 100644
--- a/xen/scripts/Kbuild.include
+++ b/xen/scripts/Kbuild.include
@@ -43,6 +43,18 @@ define as-option-add-closure
     endif
 endef
 
+# $(if-success,<command>,<then>,<else>)
+# Return <then> if <command> exits with 0, <else> otherwise.
+if-success = $(shell { $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
+
+# $(success,<command>)
+# Return y if <command> exits with 0, n otherwise
+success = $(call if-success,$(1),y,n)
+
+# $(ld-option,<flag>)
+# Return y if the linker supports <flag>, n otherwise
+ld-option = $(call success,$(LD) -v $(1))
+
 # cc-ifversion
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
 cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4))
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56740.99422 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOTt-0005Tn-Ms; Fri, 18 Dec 2020 22:44:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56740.99422; Fri, 18 Dec 2020 22:44:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOTt-0005Tf-J1; Fri, 18 Dec 2020 22:44:13 +0000
Received: by outflank-mailman (input) for mailman id 56740;
 Fri, 18 Dec 2020 22:44:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTs-0005TU-4t
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTs-00017e-42
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOTs-0007rQ-1B
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=L934xbBn46EwCsxOCo4jfX8vBuRMrun7o9jrH0oN+y4=; b=npYS0R0b76fysaf2v6KoLpwdNj
	hVn9oLLKuMnfXTxih2saRuzwiYBIjVmuJl6fO94sEJ7pLrPd7NfxBXOEL/QfCxB8OjTx8kgtjzrlj
	8xs4zSMfZqHaueDFjxkEO6QtwyvSrc/nz4mrfz+iT9TpASAxodKph7/zQFgnZTmcft0A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: switch barf[_perror]() to use syslog()
Message-Id: <E1kqOTs-0007rQ-1B@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:12 +0000

commit cbc86340ac75c8ff50e51a16c8fdbdf3d2a7c55d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:39 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: switch barf[_perror]() to use syslog()
    
    When xenstored crashes due to an unrecoverable condition it is calling
    either barf() or barf_perror() to issue a message and then exit().
    
    Make sure the message is visible somewhere by using syslog()
    additionally to xprintf(), as the latter will be visible only with
    tracing active.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/utils.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/xenstore/utils.c b/tools/xenstore/utils.c
index a1ac12584a..633ce3b4fc 100644
--- a/tools/xenstore/utils.c
+++ b/tools/xenstore/utils.c
@@ -3,6 +3,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -35,6 +36,7 @@ void barf(const char *fmt, ...)
 	va_end(arglist);
 
  	if (bytes >= 0) {
+		syslog(LOG_CRIT, "%s\n", str);
 		xprintf("%s\n", str);
 		free(str);
 	}
@@ -54,6 +56,7 @@ void barf_perror(const char *fmt, ...)
 	va_end(arglist);
 
  	if (bytes >= 0) {
+		syslog(LOG_CRIT, "%s: %s\n", str, strerror(err));
 		xprintf("%s: %s\n", str, strerror(err));
 		free(str);
 	}
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56741.99425 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOU3-0005VZ-NU; Fri, 18 Dec 2020 22:44:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56741.99425; Fri, 18 Dec 2020 22:44:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOU3-0005VR-KV; Fri, 18 Dec 2020 22:44:23 +0000
Received: by outflank-mailman (input) for mailman id 56741;
 Fri, 18 Dec 2020 22:44:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOU2-0005VE-7f
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOU2-00018A-6u
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOU2-0007sF-64
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=L1YvyOyx+U8h56cZhOb0Mr84YL0dIYDqPPD58PC5khY=; b=Gi+2grCnpR9m6S1TLmrwc9A6nv
	IiGFJweLx1pZ1/azngA27jUiUhVrTofrmwDEAuEjU/ai12fOGoP3D6ej71whk1Kn9UNNbRwk7R+Bm
	xKNPgX7cVXSHbE4zNmkpeG/MJ6m5LcSRqd+lUCGba+SCtggQ2qPW6RT0DtNuXv6cse9M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: make set_tdb_key() non-static
Message-Id: <E1kqOU2-0007sF-64@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:22 +0000

commit 2474e53726bda64fac9d604fbc2128df88b54cfb
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:40 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: make set_tdb_key() non-static
    
    set_tdb_key() can be used by destroy_node(), too. So remove the static
    attribute and move it to xenstored_core.c.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 14 +++++++++++---
 tools/xenstore/xenstored_core.h        |  2 ++
 tools/xenstore/xenstored_transaction.c |  6 ------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3082a36d3a..ab1c7835b8 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -352,6 +352,16 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
 	}
 }
 
+void set_tdb_key(const char *name, TDB_DATA *key)
+{
+	/*
+	 * Dropping const is fine here, as the key will never be modified
+	 * by TDB.
+	 */
+	key->dptr = (char *)name;
+	key->dsize = strlen(name);
+}
+
 /*
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
@@ -985,9 +995,7 @@ static int destroy_node(void *_node)
 	if (streq(node->name, "/"))
 		corrupt(NULL, "Destroying root node!");
 
-	key.dptr = (void *)node->name;
-	key.dsize = strlen(node->name);
-
+	set_tdb_key(node->name, &key);
 	tdb_delete(tdb_ctx, key);
 
 	domain_entry_dec(talloc_parent(node), node);
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 4c6c3d6f20..fb59d862a2 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -220,6 +220,8 @@ extern xengnttab_handle **xgt_handle;
 
 int remember_string(struct hashtable *hash, const char *str);
 
+void set_tdb_key(const char *name, TDB_DATA *key);
+
 #endif /* _XENSTORED_CORE_H */
 
 /*
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2881f3b2e4..52355f4ed8 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -168,12 +168,6 @@ struct transaction
 extern int quota_max_transaction;
 uint64_t generation;
 
-static void set_tdb_key(const char *name, TDB_DATA *key)
-{
-	key->dptr = (char *)name;
-	key->dsize = strlen(name);
-}
-
 static struct accessed_node *find_accessed_node(struct transaction *trans,
 						const char *name)
 {
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56742.99429 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUD-0005Wz-PU; Fri, 18 Dec 2020 22:44:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56742.99429; Fri, 18 Dec 2020 22:44:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUD-0005Wr-MA; Fri, 18 Dec 2020 22:44:33 +0000
Received: by outflank-mailman (input) for mailman id 56742;
 Fri, 18 Dec 2020 22:44:32 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUC-0005Wh-Bd
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:32 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUC-00018N-Aq
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUC-0007sw-8x
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xGzQyKq/0cNiToRS9A4naZxVKQzulbUn7lKQGxq3xr0=; b=uy7WFjYun4JvLMO2JULWpJv/XO
	WdmujHb+cIJ3UjQ6JKNH+1os1H4JQsXrY4W50gjPQnzbzxiVOdnAHmrKrnfB/pCBiURmz0uxLPKAQ
	F0KeVNxE9iazx9fz0Weh1/ehe6neP0vyLWjUcLfppU6dEI8ec/Cjgz4F4xN+7WxhEO6w=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] tools/xenstore: remove unused cruft from xenstored_domain.c
Message-Id: <E1kqOUC-0007sw-8x@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:32 +0000

commit fe733fa0998e280b400904aaf9f624c67a311414
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 17:35:41 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 17 15:04:43 2020 +0000

    tools/xenstore: remove unused cruft from xenstored_domain.c
    
    domain->remote_port and restore_existing_connections() are useless and
    can be removed.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c   |  3 ---
 tools/xenstore/xenstored_domain.c | 11 -----------
 tools/xenstore/xenstored_domain.h |  3 ---
 3 files changed, 17 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ab1c7835b8..50986f8b29 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -2087,9 +2087,6 @@ int main(int argc, char *argv[])
 	if (!no_domain_init)
 		domain_init();
 
-	/* Restore existing connections. */
-	restore_existing_connections();
-
 	if (outputpid) {
 		printf("%ld\n", (long)getpid());
 		fflush(stdout);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7d348d57f3..ed8e83b06b 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -54,10 +54,6 @@ struct domain
 	/* Event channel port */
 	evtchn_port_t port;
 
-	/* The remote end of the event channel, used only to validate
-	   repeated domain introductions. */
-	evtchn_port_t remote_port;
-
 	/* Domain path in store. */
 	char *path;
 
@@ -382,7 +378,6 @@ static int new_domain(struct domain *domain, int port)
 	domain->conn->domain = domain;
 	domain->conn->id = domain->domid;
 
-	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
@@ -470,7 +465,6 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 			xenevtchn_unbind(xce_handle, domain->port);
 		rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
 		domain->port = (rc == -1) ? 0 : rc;
-		domain->remote_port = port;
 	}
 
 	domain_conn_reset(domain);
@@ -636,11 +630,6 @@ const char *get_implicit_path(const struct connection *conn)
 	return conn->domain->path;
 }
 
-/* Restore existing connections. */
-void restore_existing_connections(void)
-{
-}
-
 static int set_dom_perms_default(struct node_perms *perms)
 {
 	perms->num = 1;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 5e00087206..66e0a12654 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -47,9 +47,6 @@ void domain_init(void);
 /* Returns the implicit path of a connection (only domains have this) */
 const char *get_implicit_path(const struct connection *conn);
 
-/* Read existing connection information from store. */
-void restore_existing_connections(void);
-
 /* Can connection attached to domain read/write. */
 bool domain_can_read(struct connection *conn);
 bool domain_can_write(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56743.99433 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUN-0005YY-SV; Fri, 18 Dec 2020 22:44:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56743.99433; Fri, 18 Dec 2020 22:44:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUN-0005YQ-PE; Fri, 18 Dec 2020 22:44:43 +0000
Received: by outflank-mailman (input) for mailman id 56743;
 Fri, 18 Dec 2020 22:44:42 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUM-0005YH-Eb
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:42 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUM-00018a-Dl
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:42 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUM-0007u2-Cw
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:42 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0n+G5P8HtgjgYiJx1lAZ5n9GpYsPOUNh/837XL+tId0=; b=Z6K124DXg07t4IfuTOJZHt/Adv
	iOT9Rv9MnpSXLkkSykBhwB6ejGC4woMbptc/yFk3H/OISCm4GUiD3bEI0q+bY3WKWYPPqZ6UIVfYk
	xg/KDHH39WeJhLgLqPdMntSOGqvqR4+rWpRH8/WYHhGxk5LlhKB58exGuOpZbxesCUqk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/cpupool: support moving domain between cpupools with different granularity
Message-Id: <E1kqOUM-0007u2-Cw@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:42 +0000

commit 70fadc41635b9b620de63f83cdf578d7ccf00a2b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:49:11 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:49:11 2020 +0100

    xen/cpupool: support moving domain between cpupools with different granularity
    
    When moving a domain between cpupools with different scheduling
    granularity the sched_units of the domain need to be adjusted.
    
    Do that by allocating new sched_units and throwing away the old ones
    in sched_move_domain().
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
---
 xen/common/sched/core.c | 120 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 89 insertions(+), 31 deletions(-)

diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index a429fc7640..9745a77eee 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -613,17 +613,45 @@ static void sched_move_irqs(const struct sched_unit *unit)
         vcpu_move_irqs(v);
 }
 
+/*
+ * Move a domain from one cpupool to another.
+ *
+ * A domain with any vcpu having temporary affinity settings will be denied
+ * to move. Hard and soft affinities will be reset.
+ *
+ * In order to support cpupools with different scheduling granularities all
+ * scheduling units are replaced by new ones.
+ *
+ * The complete move is done in the following steps:
+ * - check prerequisites (no vcpu with temporary affinities)
+ * - allocate all new data structures (scheduler specific domain data, unit
+ *   memory, scheduler specific unit data)
+ * - pause domain
+ * - temporarily move all (old) units to the same scheduling resource (this
+ *   makes the final resource assignment easier in case the new cpupool has
+ *   a larger granularity than the old one, as the scheduling locks for all
+ *   vcpus must be held for that operation)
+ * - remove old units from scheduling
+ * - set new cpupool and scheduler domain data pointers in struct domain
+ * - switch all vcpus to new units, still assigned to the old scheduling
+ *   resource
+ * - migrate all new units to scheduling resources of the new cpupool
+ * - unpause the domain
+ * - free the old memory (scheduler specific domain data, unit memory,
+ *   scheduler specific unit data)
+ */
 int sched_move_domain(struct domain *d, struct cpupool *c)
 {
     struct vcpu *v;
-    struct sched_unit *unit;
+    struct sched_unit *unit, *old_unit;
+    struct sched_unit *new_units = NULL, *old_units;
+    struct sched_unit **unit_ptr = &new_units;
     unsigned int new_p, unit_idx;
-    void **unit_priv;
     void *domdata;
-    void *unitdata;
-    struct scheduler *old_ops;
+    struct scheduler *old_ops = dom_scheduler(d);
     void *old_domdata;
     unsigned int gran = cpupool_get_granularity(c);
+    unsigned int n_units = DIV_ROUND_UP(d->max_vcpus, gran);
     int ret = 0;
 
     for_each_vcpu ( d, v )
@@ -641,53 +669,77 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
         goto out;
     }
 
-    unit_priv = xzalloc_array(void *, DIV_ROUND_UP(d->max_vcpus, gran));
-    if ( unit_priv == NULL )
+    for ( unit_idx = 0; unit_idx < n_units; unit_idx++ )
     {
-        sched_free_domdata(c->sched, domdata);
-        ret = -ENOMEM;
-        goto out;
-    }
+        unit = sched_alloc_unit_mem();
+        if ( unit )
+        {
+            /* Initialize unit for sched_alloc_udata() to work. */
+            unit->domain = d;
+            unit->unit_id = unit_idx * gran;
+            unit->vcpu_list = d->vcpu[unit->unit_id];
+            unit->priv = sched_alloc_udata(c->sched, unit, domdata);
+            *unit_ptr = unit;
+        }
 
-    unit_idx = 0;
-    for_each_sched_unit ( d, unit )
-    {
-        unit_priv[unit_idx] = sched_alloc_udata(c->sched, unit, domdata);
-        if ( unit_priv[unit_idx] == NULL )
+        if ( !unit || !unit->priv )
         {
-            for ( unit_idx = 0; unit_priv[unit_idx]; unit_idx++ )
-                sched_free_udata(c->sched, unit_priv[unit_idx]);
-            xfree(unit_priv);
-            sched_free_domdata(c->sched, domdata);
+            old_units = new_units;
+            old_domdata = domdata;
             ret = -ENOMEM;
-            goto out;
+            goto out_free;
         }
-        unit_idx++;
+
+        unit_ptr = &unit->next_in_list;
     }
 
     domain_pause(d);
 
-    old_ops = dom_scheduler(d);
     old_domdata = d->sched_priv;
 
+    /*
+     * Temporarily move all units to same processor to make locking
+     * easier when moving the new units to the new processors.
+     */
+    new_p = cpumask_first(d->cpupool->cpu_valid);
     for_each_sched_unit ( d, unit )
     {
+        spinlock_t *lock = unit_schedule_lock_irq(unit);
+
+        sched_set_res(unit, get_sched_res(new_p));
+        spin_unlock_irq(lock);
+
         sched_remove_unit(old_ops, unit);
     }
 
+    old_units = d->sched_unit_list;
+
     d->cpupool = c;
     d->sched_priv = domdata;
 
+    unit = new_units;
+    for_each_vcpu ( d, v )
+    {
+        old_unit = v->sched_unit;
+        if ( unit->unit_id + gran == v->vcpu_id )
+            unit = unit->next_in_list;
+
+        unit->state_entry_time = old_unit->state_entry_time;
+        unit->runstate_cnt[v->runstate.state]++;
+        /* Temporarily use old resource assignment */
+        unit->res = get_sched_res(new_p);
+
+        v->sched_unit = unit;
+    }
+
+    d->sched_unit_list = new_units;
+
     new_p = cpumask_first(c->cpu_valid);
-    unit_idx = 0;
     for_each_sched_unit ( d, unit )
     {
         spinlock_t *lock;
         unsigned int unit_p = new_p;
 
-        unitdata = unit->priv;
-        unit->priv = unit_priv[unit_idx];
-
         for_each_sched_unit_vcpu ( unit, v )
         {
             migrate_timer(&v->periodic_timer, new_p);
@@ -713,8 +765,6 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
 
         sched_insert_unit(c->sched, unit);
 
-        sched_free_udata(old_ops, unitdata);
-
         unit_idx++;
     }
 
@@ -722,11 +772,19 @@ int sched_move_domain(struct domain *d, struct cpupool *c)
 
     domain_unpause(d);
 
-    sched_free_domdata(old_ops, old_domdata);
+ out_free:
+    for ( unit = old_units; unit; )
+    {
+        if ( unit->priv )
+            sched_free_udata(c->sched, unit->priv);
+        old_unit = unit;
+        unit = unit->next_in_list;
+        xfree(old_unit);
+    }
 
-    xfree(unit_priv);
+    sched_free_domdata(old_ops, old_domdata);
 
-out:
+ out:
     rcu_read_unlock(&sched_res_rculock);
 
     return ret;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:44:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:44:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56744.99437 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUX-0005Zl-U5; Fri, 18 Dec 2020 22:44:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56744.99437; Fri, 18 Dec 2020 22:44:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUX-0005Zf-Qj; Fri, 18 Dec 2020 22:44:53 +0000
Received: by outflank-mailman (input) for mailman id 56744;
 Fri, 18 Dec 2020 22:44:52 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUW-0005ZV-HM
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:52 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUW-00018i-Gd
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:52 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUW-0007ux-Fi
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:44:52 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=soveZeZjFYOkD9taNWmeTycixHNM+Z4NG+1AQMM0NKg=; b=Zx+TIxtO59DTJ+Xf8xiPbcwlQS
	gkvtyMnPqv+M/LiVuZvg/sGMWJmKDwcrITxmbMssjtiu+jFCcy6hilTaqHgSlfaqGcLcC23Fj2kuc
	NgjE8fpeejOXTeCTh7covV1WYsaX6+75IFTzMT6ZJgti7zzRSiBTkSpyrsLwwH/j7wog=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/hypfs: switch write function handles to const
Message-Id: <E1kqOUW-0007ux-Fi@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:44:52 +0000

commit fbb2b92de0782b4ea183377e014d941fbec0bab7
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:49:49 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:49:49 2020 +0100

    xen/hypfs: switch write function handles to const
    
    The node specific write functions take a void user address handle as
    parameter. As a write won't change the user memory use a const_void
    handle instead.
    
    This requires a new macro for casting a guest handle to a const type.
    
    Suggested-by: Jan Beulich <jbeulich@suse.com>
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c             | 17 +++++++++++------
 xen/include/xen/guest_access.h |  5 +++++
 xen/include/xen/hypfs.h        | 14 +++++++++-----
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 2e8e90591e..6f822ae097 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -344,7 +344,8 @@ static int hypfs_read(const struct hypfs_entry *entry,
 }
 
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     char *buf;
     int ret;
@@ -384,7 +385,8 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     bool buf;
 
@@ -405,7 +407,8 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned int ulen)
 {
     struct param_hypfs *p;
     char *buf;
@@ -439,13 +442,15 @@ int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
 }
 
 int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen)
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen)
 {
     return -EACCES;
 }
 
 static int hypfs_write(struct hypfs_entry *entry,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned long ulen)
 {
     struct hypfs_entry_leaf *l;
 
@@ -497,7 +502,7 @@ long do_hypfs_op(unsigned int cmd,
         break;
 
     case XEN_HYPFS_OP_write_contents:
-        ret = hypfs_write(entry, arg3, arg4);
+        ret = hypfs_write(entry, guest_handle_const_cast(arg3, void), arg4);
         break;
 
     default:
diff --git a/xen/include/xen/guest_access.h b/xen/include/xen/guest_access.h
index f9b94cf1f4..af33ae3ab6 100644
--- a/xen/include/xen/guest_access.h
+++ b/xen/include/xen/guest_access.h
@@ -26,6 +26,11 @@
     type *_x = (hnd).p;                         \
     (XEN_GUEST_HANDLE_PARAM(type)) { _x };      \
 })
+/* Same for casting to a const type. */
+#define guest_handle_const_cast(hnd, type) ({      \
+    const type *p_ = (hnd).p;                      \
+    (XEN_GUEST_HANDLE_PARAM(const_##type)) { p_ }; \
+})
 
 /* Cast a XEN_GUEST_HANDLE to XEN_GUEST_HANDLE_PARAM */
 #define guest_handle_to_param(hnd, type) ({                  \
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 53f50772b4..99fd4b036d 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -38,7 +38,7 @@ struct hypfs_funcs {
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
-                 XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                 XEN_GUEST_HANDLE_PARAM(const_void) uaddr, unsigned int ulen);
     unsigned int (*getsize)(const struct hypfs_entry *entry);
     struct hypfs_entry *(*findentry)(const struct hypfs_entry_dir *dir,
                                      const char *name, unsigned int name_len);
@@ -154,13 +154,17 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
 int hypfs_read_leaf(const struct hypfs_entry *entry,
                     XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_write_deny(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_leaf(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
-                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                     XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                     unsigned int ulen);
 int hypfs_write_custom(struct hypfs_entry_leaf *leaf,
-                       XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned int ulen);
+                       XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                       unsigned int ulen);
 unsigned int hypfs_getsize(const struct hypfs_entry *entry);
 struct hypfs_entry *hypfs_leaf_findentry(const struct hypfs_entry_dir *dir,
                                          const char *name,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Fri Dec 18 22:45:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Fri, 18 Dec 2020 22:45:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56745.99441 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUh-0005b2-VH; Fri, 18 Dec 2020 22:45:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56745.99441; Fri, 18 Dec 2020 22:45:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqOUh-0005av-SL; Fri, 18 Dec 2020 22:45:03 +0000
Received: by outflank-mailman (input) for mailman id 56745;
 Fri, 18 Dec 2020 22:45:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUg-0005ao-KD
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:45:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUg-00019F-JR
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:45:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqOUg-0007y6-Ie
 for xen-changelog@lists.xenproject.org; Fri, 18 Dec 2020 22:45:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vrv8GGSECW+mSxxbPgysnBjmCP9EuJu4j7ThJL8iIrE=; b=4jmuXjzcF+5SOl7gKjzw1tRxMy
	pGtvKCI/Az/b1JT7IqI49U/BWnUarx/SBQ1dm404zE2w9oN2Gce+VMG66jz5UUrFwwDyWRtC4+3UA
	qRTUV+Z9uMlQTQ80+brWuoIasScm4fQD3cGaUHZm7uln7o7UVdm8neosGH/5djNWIung=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/hypfs: add new enter() and exit() per node callbacks
Message-Id: <E1kqOUg-0007y6-Ie@xenbits.xenproject.org>
Date: Fri, 18 Dec 2020 22:45:02 +0000

commit 641723f78d3a0b1982e1cd2ef37d8d877cfe542d
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Dec 17 16:50:21 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 16:50:21 2020 +0100

    xen/hypfs: add new enter() and exit() per node callbacks
    
    In order to better support resource allocation and locking for dynamic
    hypfs nodes add enter() and exit() callbacks to struct hypfs_funcs.
    
    The enter() callback is called when entering a node during hypfs user
    actions (traversing, reading or writing it), while the exit() callback
    is called when leaving a node (accessing another node at the same or a
    higher directory level, or when returning to the user).
    
    For avoiding recursion this requires a parent pointer in each node.
    Let the enter() callback return the entry address which is stored as
    the last accessed node in order to be able to use a template entry for
    that purpose in case of dynamic entries.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/hypfs.c      | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/hypfs.h |  5 ++++
 2 files changed, 82 insertions(+)

diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c
index 6f822ae097..73497ea1d7 100644
--- a/xen/common/hypfs.c
+++ b/xen/common/hypfs.c
@@ -25,30 +25,40 @@ CHECK_hypfs_dirlistentry;
      ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry)))
 
 const struct hypfs_funcs hypfs_dir_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_dir,
     .write = hypfs_write_deny,
     .getsize = hypfs_getsize,
     .findentry = hypfs_dir_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_ro_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_deny,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_leaf_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_leaf,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_bool_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_bool,
     .getsize = hypfs_getsize,
     .findentry = hypfs_leaf_findentry,
 };
 const struct hypfs_funcs hypfs_custom_wr_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
     .read = hypfs_read_leaf,
     .write = hypfs_write_custom,
     .getsize = hypfs_getsize,
@@ -63,6 +73,8 @@ enum hypfs_lock_state {
 };
 static DEFINE_PER_CPU(enum hypfs_lock_state, hypfs_locked);
 
+static DEFINE_PER_CPU(const struct hypfs_entry *, hypfs_last_node_entered);
+
 HYPFS_DIR_INIT(hypfs_root, "");
 
 static void hypfs_read_lock(void)
@@ -100,11 +112,56 @@ static void hypfs_unlock(void)
     }
 }
 
+const struct hypfs_entry *hypfs_node_enter(const struct hypfs_entry *entry)
+{
+    return entry;
+}
+
+void hypfs_node_exit(const struct hypfs_entry *entry)
+{
+}
+
+static int node_enter(const struct hypfs_entry *entry)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    entry = entry->funcs->enter(entry);
+    if ( IS_ERR(entry) )
+        return PTR_ERR(entry);
+
+    ASSERT(entry);
+    ASSERT(!*last || *last == entry->parent);
+
+    *last = entry;
+
+    return 0;
+}
+
+static void node_exit(const struct hypfs_entry *entry)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    ASSERT(*last == entry);
+    *last = entry->parent;
+
+    entry->funcs->exit(entry);
+}
+
+static void node_exit_all(void)
+{
+    const struct hypfs_entry **last = &this_cpu(hypfs_last_node_entered);
+
+    while ( *last )
+        node_exit(*last);
+}
+
 static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
 {
     int ret = -ENOENT;
     struct hypfs_entry *e;
 
+    ASSERT(new->funcs->enter);
+    ASSERT(new->funcs->exit);
     ASSERT(new->funcs->read);
     ASSERT(new->funcs->write);
     ASSERT(new->funcs->getsize);
@@ -140,6 +197,7 @@ static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new)
         unsigned int sz = strlen(new->name);
 
         parent->e.size += DIRENTRY_SIZE(sz);
+        new->parent = &parent->e;
     }
 
     hypfs_unlock();
@@ -221,6 +279,7 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
     const char *end;
     struct hypfs_entry *entry;
     unsigned int name_len;
+    int ret;
 
     for ( ; ; )
     {
@@ -235,6 +294,10 @@ static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir,
             end = strchr(path, '\0');
         name_len = end - path;
 
+        ret = node_enter(&dir->e);
+        if ( ret )
+            return ERR_PTR(ret);
+
         entry = dir->e.funcs->findentry(dir, path, name_len);
         if ( IS_ERR(entry) || !*end )
             return entry;
@@ -265,6 +328,7 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
     const struct hypfs_entry_dir *d;
     const struct hypfs_entry *e;
     unsigned int size = entry->funcs->getsize(entry);
+    int ret;
 
     ASSERT(this_cpu(hypfs_locked) != hypfs_unlocked);
 
@@ -276,12 +340,19 @@ int hypfs_read_dir(const struct hypfs_entry *entry,
         unsigned int e_namelen = strlen(e->name);
         unsigned int e_len = DIRENTRY_SIZE(e_namelen);
 
+        ret = node_enter(e);
+        if ( ret )
+            return ret;
+
         direntry.e.pad = 0;
         direntry.e.type = e->type;
         direntry.e.encoding = e->encoding;
         direntry.e.content_len = e->funcs->getsize(e);
         direntry.e.max_write_len = e->max_size;
         direntry.off_next = list_is_last(&e->list, &d->dirlist) ? 0 : e_len;
+
+        node_exit(e);
+
         if ( copy_to_guest(uaddr, &direntry, 1) )
             return -EFAULT;
 
@@ -495,6 +566,10 @@ long do_hypfs_op(unsigned int cmd,
         goto out;
     }
 
+    ret = node_enter(entry);
+    if ( ret )
+        goto out;
+
     switch ( cmd )
     {
     case XEN_HYPFS_OP_read:
@@ -511,6 +586,8 @@ long do_hypfs_op(unsigned int cmd,
     }
 
  out:
+    node_exit_all();
+
     hypfs_unlock();
 
     return ret;
diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h
index 99fd4b036d..a6dfdb7d8e 100644
--- a/xen/include/xen/hypfs.h
+++ b/xen/include/xen/hypfs.h
@@ -35,6 +35,8 @@ struct hypfs_entry;
  * "/a/b/c" findentry() will be called for "/", "/a", and "/a/b").
  */
 struct hypfs_funcs {
+    const struct hypfs_entry *(*enter)(const struct hypfs_entry *entry);
+    void (*exit)(const struct hypfs_entry *entry);
     int (*read)(const struct hypfs_entry *entry,
                 XEN_GUEST_HANDLE_PARAM(void) uaddr);
     int (*write)(struct hypfs_entry_leaf *leaf,
@@ -56,6 +58,7 @@ struct hypfs_entry {
     unsigned int size;
     unsigned int max_size;
     const char *name;
+    struct hypfs_entry *parent;
     struct list_head list;
     const struct hypfs_funcs *funcs;
 };
@@ -149,6 +152,8 @@ int hypfs_add_dir(struct hypfs_entry_dir *parent,
                   struct hypfs_entry_dir *dir, bool nofault);
 int hypfs_add_leaf(struct hypfs_entry_dir *parent,
                    struct hypfs_entry_leaf *leaf, bool nofault);
+const struct hypfs_entry *hypfs_node_enter(const struct hypfs_entry *entry);
+void hypfs_node_exit(const struct hypfs_entry *entry);
 int hypfs_read_dir(const struct hypfs_entry *entry,
                    XEN_GUEST_HANDLE_PARAM(void) uaddr);
 int hypfs_read_leaf(const struct hypfs_entry *entry,
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 17:22:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 17:22:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56961.99655 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqfve-00070U-P6; Sat, 19 Dec 2020 17:22:02 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56961.99655; Sat, 19 Dec 2020 17:22:02 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqfve-00070M-Lm; Sat, 19 Dec 2020 17:22:02 +0000
Received: by outflank-mailman (input) for mailman id 56961;
 Sat, 19 Dec 2020 17:22:01 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqfvd-00070E-L7
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 17:22:01 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqfvd-00032Q-KG
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 17:22:01 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqfvd-0002cB-Ih
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 17:22:01 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=GfXskdN7uLIK3/NXzSBc+ATJcdgTT6dUz8Zmq72auSc=; b=eaRMrUf4Q4AoA27jZGPmBlhCtv
	ubM3gq/kdGC4c3KECQe6wBS4GIOjGMMVOkN+ffNNxjtvN8c8nM20B9ZcmTgscrIoN/V1tL0L702mz
	y4hS7Pf41u16FZytG8czni0zCrnolB+Xa9MI1cKo0Z08VU5VzbssRfCthesBpnyfXNMk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.14] update Xen version to 4.14.1
Message-Id: <E1kqfvd-0002cB-Ih@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 17:22:01 +0000

commit ad844aa352559a8b1f36e391a27d9d7dbddbdc36
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Thu Dec 17 17:47:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Thu Dec 17 17:47:25 2020 +0100

    update Xen version to 4.14.1
---
 Config.mk    | 6 +++---
 xen/Makefile | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Config.mk b/Config.mk
index 264dc0d27d..bc4ee6fe34 100644
--- a/Config.mk
+++ b/Config.mk
@@ -245,15 +245,15 @@ SEABIOS_UPSTREAM_URL ?= git://xenbits.xen.org/seabios.git
 MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
 endif
 OVMF_UPSTREAM_REVISION ?= 20d2e5a125e34fc8501026613a71549b2a1a3e54
-QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.0
-MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.0
+QEMU_UPSTREAM_REVISION ?= qemu-xen-4.14.1
+MINIOS_UPSTREAM_REVISION ?= xen-RELEASE-4.14.1
 
 SEABIOS_UPSTREAM_REVISION ?= rel-1.13.0
 
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= xen-4.14.0
+QEMU_TRADITIONAL_REVISION ?= xen-4.14.1
 
 # Specify which qemu-dm to use. This may be `ioemu' to use the old
 # Mercurial in-tree version, or a local directory, or a git URL.
diff --git a/xen/Makefile b/xen/Makefile
index 110ea0f1a8..df7cf10be3 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 14
-export XEN_EXTRAVERSION ?= .1-pre$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .1$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.14


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56988.99677 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm40-0002Hi-F5; Sat, 19 Dec 2020 23:55:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56988.99677; Sat, 19 Dec 2020 23:55:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm40-0002Ha-C8; Sat, 19 Dec 2020 23:55:04 +0000
Received: by outflank-mailman (input) for mailman id 56988;
 Sat, 19 Dec 2020 23:55:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm3y-0002HV-Rl
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm3y-0001Hg-OW
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm3y-0007Ac-Mj
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=QJvHOGF7vuQ8hyNs0gViiAhZl9K8QwwGXiOTRd0MmN0=; b=XMv+3znPbF+RMmsn0FmAHBvaFg
	cwyC5TiWQlUIhPDCsTXZDceFYR5pSCQ3cWHCcTuq26mv4xvCnolFqk0l4Lni8C9IptdRJ+7ryQo3I
	G0zgpxYt4THA7ydjw9gXgrlm91shqEfmZSmE+XcasCxZzq3ONwQPeD5JIM3dctQ+e0pY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add a QEMU aarch64 smoke test
Message-Id: <E1kqm3y-0007Ac-Mj@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:02 +0000

commit dbc1e724bbcddf5de7a591ba7eb5a765a72de951
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Thu Nov 12 18:30:33 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add a QEMU aarch64 smoke test
    
    Use QEMU to start Xen (just the hypervisor) up until it stops because
    there is no dom0 kernel to boot.
    
    It is based on the existing build job unstable-arm64v8.
    
    Also use make -j$(nproc) to build Xen.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml         | 22 ++++++++++++++++++++++
 automation/scripts/build               |  6 +++---
 automation/scripts/qemu-smoke-arm64.sh | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index 793feafe8b..35346e3f6e 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -22,6 +22,28 @@ build-each-commit-gcc:
     - /^coverity-tested\/.*/
     - /^stable-.*/
 
+qemu-smoke-arm64-gcc:
+  stage: test
+  image: registry.gitlab.com/xen-project/xen/${CONTAINER}
+  variables:
+    CONTAINER: debian:unstable-arm64v8
+  script:
+    - ./automation/scripts/qemu-smoke-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
+  dependencies:
+    - debian-unstable-gcc-arm64
+  artifacts:
+    paths:
+      - smoke.serial
+      - '*.log'
+    when: always
+  tags:
+    - arm64
+  except:
+    - master
+    - smoke
+    - /^coverity-tested\/.*/
+    - /^stable-.*/
+
 qemu-smoke-x86-64-gcc:
   stage: test
   image: registry.gitlab.com/xen-project/xen/${CONTAINER}
diff --git a/automation/scripts/build b/automation/scripts/build
index 0cd0f3971d..7038e5eb50 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -10,9 +10,9 @@ cc-ver()
 
 # random config or default config
 if [[ "${RANDCONFIG}" == "y" ]]; then
-    make -C xen KCONFIG_ALLCONFIG=tools/kconfig/allrandom.config randconfig
+    make -j$(nproc) -C xen KCONFIG_ALLCONFIG=tools/kconfig/allrandom.config randconfig
 else
-    make -C xen defconfig
+    make -j$(nproc) -C xen defconfig
 fi
 
 # build up our configure options
@@ -45,7 +45,7 @@ make -j$(nproc) dist
 # Extract artifacts to avoid getting rewritten by customised builds
 cp xen/.config xen-config
 mkdir binaries
-if [[ "${XEN_TARGET_ARCH}" == "x86_64" ]]; then
+if [[ "${XEN_TARGET_ARCH}" != "x86_32" ]]; then
     cp xen/xen binaries/xen
 fi
 
diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
new file mode 100755
index 0000000000..1a0a98be6d
--- /dev/null
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -ex
+
+# Install QEMU
+export DEBIAN_FRONTENT=noninteractive
+apt-get -qy update
+apt-get -qy install --no-install-recommends qemu-system-aarch64 \
+                                            u-boot-qemu
+
+# XXX Silly workaround to get the following QEMU command to work
+# QEMU looks for "efi-virtio.rom" even if it is unneeded
+cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
+qemu-system-aarch64 \
+   -machine virtualization=true \
+   -cpu cortex-a57 -machine type=virt \
+   -m 512 -display none \
+   -machine dumpdtb=binaries/virt-gicv3.dtb
+
+rm -f smoke.serial
+set +e
+echo "  booti 0x49000000 - 0x44000000" | timeout -k 1 30 qemu-system-aarch64 \
+    -machine virtualization=true \
+    -cpu cortex-a57 -machine type=virt \
+    -m 512 -monitor none -serial stdio \
+    -no-reboot \
+    -device loader,file=binaries/virt-gicv3.dtb,force-raw=on,addr=0x44000000 \
+    -device loader,file=binaries/xen,force-raw=on,addr=0x49000000 \
+    -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
+
+set -e
+grep -q 'LOADING DOMAIN 0' smoke.serial || exit 1
+exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56989.99681 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4A-0002IP-GV; Sat, 19 Dec 2020 23:55:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56989.99681; Sat, 19 Dec 2020 23:55:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4A-0002IH-Dd; Sat, 19 Dec 2020 23:55:14 +0000
Received: by outflank-mailman (input) for mailman id 56989;
 Sat, 19 Dec 2020 23:55:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm48-0002IC-T2
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm48-0001Hl-Rs
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm48-0007BE-QR
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=i114CwATJVEA5nbpWCgYsJPO/T8FsHrcbaAzaU+uerE=; b=NMLVWNSiX47k0fgO9Xl9OasJIJ
	lFcZT55vUF+QPS1Up7W8fMkA6dFXhyAzSYgxLrNgyELK8BWdSpSs87gKyM3gDLDyqTire3nl+1CMb
	oC2l4dXA/2O/QJf1OkbCT5pVzJqPeQPSchIP+80Ng67Q6nl3pdlq23uSxVEOxDnfCkZI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add dom0less to the QEMU aarch64 smoke test
Message-Id: <E1kqm48-0007BE-QR@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:12 +0000

commit 8c5e5e85aa9908f2f3fbf110ef4341e5eba61657
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 13 15:22:41 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add dom0less to the QEMU aarch64 smoke test
    
    Add a trivial dom0less test:
    - fetch the Debian arm64 kernel and use it ad dom0/U kernel
    - use busybox-static to create a trivial dom0/U ramdisk
    - use ImageBuilder to generate the uboot boot script automatically
    - install and use u-boot from the Debian package to start the test
    - binaries are loaded from uboot via tftp
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/qemu-smoke-arm64.sh | 81 +++++++++++++++++++++++++++++++---
 1 file changed, 74 insertions(+), 7 deletions(-)

diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
index 1a0a98be6d..794c53f887 100755
--- a/automation/scripts/qemu-smoke-arm64.sh
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -6,7 +6,17 @@ set -ex
 export DEBIAN_FRONTENT=noninteractive
 apt-get -qy update
 apt-get -qy install --no-install-recommends qemu-system-aarch64 \
-                                            u-boot-qemu
+                                            u-boot-qemu \
+                                            u-boot-tools \
+                                            device-tree-compiler \
+                                            busybox-static \
+                                            cpio
+
+cd binaries
+apt-get download linux-image-*[0-9]-arm64
+dpkg -i --ignore-depends=initramfs-tools ./linux-image-*arm64.deb || true
+cp /boot/vmlinuz-*arm64 ./Image
+cd ..
 
 # XXX Silly workaround to get the following QEMU command to work
 # QEMU looks for "efi-virtio.rom" even if it is unneeded
@@ -14,20 +24,77 @@ cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
 qemu-system-aarch64 \
    -machine virtualization=true \
    -cpu cortex-a57 -machine type=virt \
-   -m 512 -display none \
+   -m 1024 -display none \
    -machine dumpdtb=binaries/virt-gicv3.dtb
+# XXX disable pl061 to avoid Linux crash
+dtc -I dtb -O dts binaries/virt-gicv3.dtb > binaries/virt-gicv3.dts
+sed 's/compatible = "arm,pl061.*/status = "disabled";/g' binaries/virt-gicv3.dts > binaries/virt-gicv3-edited.dts
+dtc -I dts -O dtb binaries/virt-gicv3-edited.dts > binaries/virt-gicv3.dtb
+
+
+# Busybox Dom0
+mkdir -p initrd
+mkdir -p initrd/bin
+mkdir -p initrd/sbin
+mkdir -p initrd/etc
+mkdir -p initrd/dev
+mkdir -p initrd/proc
+mkdir -p initrd/sys
+mkdir -p initrd/lib
+mkdir -p initrd/var
+mkdir -p initrd/mnt
+cp /bin/busybox initrd/bin/busybox
+initrd/bin/busybox --install initrd/bin
+echo "#!/bin/sh
+
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devtmpfs devtmpfs /dev
+/bin/sh" > initrd/init
+chmod +x initrd/init
+cd initrd
+find . | cpio --create --format='newc' | gzip > ../binaries/initrd
+cd ..
+
+
+# ImageBuilder
+echo 'MEMORY_START="0x40000000"
+MEMORY_END="0x80000000"
 
+DEVICE_TREE="virt-gicv3.dtb"
+XEN="xen"
+DOM0_KERNEL="Image"
+DOM0_RAMDISK="initrd"
+XEN_CMD="console=dtuart dom0_mem=512M"
+
+NUM_DOMUS=1
+DOMU_KERNEL[0]="Image"
+DOMU_RAMDISK[0]="initrd"
+DOMU_MEM[0]="256"
+
+LOAD_CMD="tftpb"
+UBOOT_SOURCE="boot.source"
+UBOOT_SCRIPT="boot.scr"' > binaries/config
+rm -rf imagebuilder
+git clone https://gitlab.com/ViryaOS/imagebuilder
+bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/config
+
+
+# Run the test
 rm -f smoke.serial
 set +e
-echo "  booti 0x49000000 - 0x44000000" | timeout -k 1 30 qemu-system-aarch64 \
+echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
+timeout -k 1 240 \
+qemu-system-aarch64 \
     -machine virtualization=true \
     -cpu cortex-a57 -machine type=virt \
-    -m 512 -monitor none -serial stdio \
+    -m 1024 -monitor none -serial stdio \
+    -smp 2 \
     -no-reboot \
-    -device loader,file=binaries/virt-gicv3.dtb,force-raw=on,addr=0x44000000 \
-    -device loader,file=binaries/xen,force-raw=on,addr=0x49000000 \
+    -device virtio-net-pci,netdev=n0 \
+    -netdev user,id=n0,tftp=binaries \
     -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
 
 set -e
-grep -q 'LOADING DOMAIN 0' smoke.serial || exit 1
+(grep -q "^BusyBox" smoke.serial && grep -q "DOM1: BusyBox" smoke.serial) || exit 1
 exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56990.99684 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4K-0002Jp-Hz; Sat, 19 Dec 2020 23:55:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56990.99684; Sat, 19 Dec 2020 23:55:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4K-0002Ji-F9; Sat, 19 Dec 2020 23:55:24 +0000
Received: by outflank-mailman (input) for mailman id 56990;
 Sat, 19 Dec 2020 23:55:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4J-0002JV-0y
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4I-0001Hu-VK
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4I-0007CU-Tr
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wwWYZSRuI7FhhQi/G016dorh/5I4UPrRbqY9ZjOV3II=; b=UyAYih4Nh5t9uGBsiiMZt4TCVy
	uqCH2RsX8JRKbUJ9tpvJ/nSOm/w/xmT734qzQbs+ckoz2BN13Wd8eGNH8V4YcL8xuSutcmuARCcsj
	vqz/eFpK7utOXfd2fA6mvOTiArYSpHVcbIQn9P+l21hSW9V8DUTPHIxW5v3mT2ArZWkE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: special configure flags for musl-based systems
Message-Id: <E1kqm4I-0007CU-Tr@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:22 +0000

commit 3a51115ab50fd2561b94cb6ec0a597db81549240
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Thu Nov 19 19:20:15 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: special configure flags for musl-based systems
    
    QEMU upstream builds with warnings when libc is musl:
    
      #warning redirecting incorrect #include <sys/signal.h> to <signal.h>
    
    Disable -Werror by passing --disable-werror to the QEMUU config script
    if libc is musl.
    
    hvmloader doesn't build on musl systems today. Disable any guest
    firmware build.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/build | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/automation/scripts/build b/automation/scripts/build
index 7038e5eb50..959a26d084 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -28,6 +28,14 @@ if [[ "${CC}" == "clang"* ]]; then
     cfgargs+=("--disable-stubdom")
 fi
 
+if ! test -z "$(ldd /bin/ls|grep musl|head -1)"; then
+    # disable --disable-werror for QEMUU when building with MUSL
+    cfgargs+=("--with-extra-qemuu-configure-args=\"--disable-werror\"")
+    # hvmloader doesn't build on MUSL systems
+    cfgargs+=("--disable-seabios")
+    cfgargs+=("--disable-rombios")
+fi
+
 # Qemu requires Python 3.5 or later
 if ! type python3 || python3 -c "import sys; res = sys.version_info < (3, 5); exit(not(res))"; then
     cfgargs+=("--with-system-qemu=/bin/false")
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56991.99689 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4U-0002LH-Jm; Sat, 19 Dec 2020 23:55:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56991.99689; Sat, 19 Dec 2020 23:55:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4U-0002LA-Gl; Sat, 19 Dec 2020 23:55:34 +0000
Received: by outflank-mailman (input) for mailman id 56991;
 Sat, 19 Dec 2020 23:55:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4T-0002Kz-2f
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4T-0001I9-1v
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4T-0007D3-0z
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/xkFmokjAEwJgRTD+xIjc3+vYLyweE4PY34IDqs+iJw=; b=dGUC7EYcpxHtNIFmvzdrBWUeYB
	lfOLVgAQ/OxQ5TTLTlKMFKrLYY4cZkZWp1MVdWLg41vJEgm5u0z0ZZ/ChCfsrU9cFSKkz0Dl3NgEP
	F3WdfPUhBM16wldcVCtwTH4khQWnbj5Aa+0fiK2Jhxg+zgSsJ4kmyAcL4JO5ALpIsmqU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add alpine linux 3.12 arm64 build container
Message-Id: <E1kqm4T-0007D3-0z@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:33 +0000

commit 335ddd8ff62e67b02ad794cadb671f843159a29c
Author:     Stefano Stabellini <stefano.stabellini@xilinx.com>
AuthorDate: Tue Nov 17 17:03:55 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux 3.12 arm64 build container
    
    The build container will be used for a new Alpine Linux 3.12 arm64 build
    test.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/build/alpine/3.12-arm64v8.dockerfile | 52 +++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/automation/build/alpine/3.12-arm64v8.dockerfile b/automation/build/alpine/3.12-arm64v8.dockerfile
new file mode 100644
index 0000000000..d6cdf5b200
--- /dev/null
+++ b/automation/build/alpine/3.12-arm64v8.dockerfile
@@ -0,0 +1,52 @@
+FROM arm64v8/alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen build deps
+  apk add argp-standalone && \
+  apk add autoconf && \
+  apk add automake && \
+  apk add bash && \
+  apk add curl && \
+  apk add curl-dev && \
+  apk add dev86 && \
+  apk add dtc-dev && \
+  apk add gcc  && \
+  apk add gettext && \
+  apk add git && \
+  apk add iasl && \
+  apk add libaio-dev && \
+  apk add libfdt && \
+  apk add linux-headers && \
+  apk add make && \
+  apk add musl-dev  && \
+  apk add ncurses-dev && \
+  apk add patch  && \
+  apk add python3-dev && \
+  apk add texinfo && \
+  apk add util-linux-dev && \
+  apk add xz-dev && \
+  apk add yajl-dev && \
+  apk add zlib-dev && \
+  \
+  # qemu build deps
+  apk add bison && \
+  apk add flex && \
+  apk add glib-dev && \
+  apk add libattr && \
+  apk add libcap-ng-dev && \
+  apk add pixman-dev && \
+  \
+  # cleanup
+  rm -rf /tmp/* && \
+  rm -f /var/cache/apk/*
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56992.99692 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4d-0002N7-LG; Sat, 19 Dec 2020 23:55:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56992.99692; Sat, 19 Dec 2020 23:55:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4d-0002Mz-IL; Sat, 19 Dec 2020 23:55:43 +0000
Received: by outflank-mailman (input) for mailman id 56992;
 Sat, 19 Dec 2020 23:55:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4d-0002Ms-6c
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4d-0001IY-5s
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4d-0007Dl-3q
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Dq5nAFH/Sq7U5YWG4sXFQczlYSNTnXKgqsH4OJymWQs=; b=hWaMZM8FVk6yjjfwrPPBg7MLYd
	iMU0RHRBdx0PvvtndHFCT2uCTsMV0f1RAxT2Bdl+R2Rpx6FzeNX7iQnOJV5BOTQ0Wup18BuRGPYln
	nSS/zbZJtZpyTTU9GKTVw/ke/INbSCkF8kbIhbPigARP5ihM/+Y1LvN+RG5Vo/dVuy2c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add alpine linux arm64 build test
Message-Id: <E1kqm4d-0007Dl-3q@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:43 +0000

commit c5f8e7d613b8e68b61e6895bd5914e4868aa3013
Author:     Stefano Stabellini <stefano.stabellini@xilinx.com>
AuthorDate: Tue Nov 17 17:07:43 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux arm64 build test
    
    Based on the arm64 3.12 build container
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index 4bd1cfc1c0..fa38c39d6a 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -434,3 +434,12 @@ debian-unstable-gcc-debug-arm64-randconfig:
     CONTAINER: debian:unstable-arm64v8
     RANDCONFIG: y
 
+alpine-3.12-gcc-arm64:
+  extends: .gcc-arm64-build
+  variables:
+    CONTAINER: alpine:3.12-arm64v8
+
+alpine-3.12-gcc-debug-arm64:
+  extends: .gcc-arm64-build-debug
+  variables:
+    CONTAINER: alpine:3.12-arm64v8
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:55:53 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:55:53 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56993.99697 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4n-0002OX-My; Sat, 19 Dec 2020 23:55:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56993.99697; Sat, 19 Dec 2020 23:55:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4n-0002OQ-Jq; Sat, 19 Dec 2020 23:55:53 +0000
Received: by outflank-mailman (input) for mailman id 56993;
 Sat, 19 Dec 2020 23:55:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4n-0002OK-9v
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4n-0001Iq-8i
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4n-0007Ef-7r
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:55:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wBqO9ughDRvIr2HzW1gi2jA2lABh2CiP5mhtX3J+AOk=; b=jcNh998TEhcri8ZmrOJSIzGKY3
	Ybl012YOVNj/iaPxKZBmiJ41rXexyOjAjsWjKNMH9nT7A6MBz26UsxnlQAB6f+rdvQ9VFs1kJWax1
	LXxAswYWDD9rLlEMFttZSOzVvKJgc5aYKg74O6tv8g0hx99HE5Umz7pjY8Qx9y+zrqVE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add alpine linux 3.12 x86 build container
Message-Id: <E1kqm4n-0007Ef-7r@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:55:53 +0000

commit a9afe7768bdae3e22aec5fe67360e46f8f3e3cea
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 20 09:54:01 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux 3.12 x86 build container
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/build/alpine/3.12.dockerfile | 52 +++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/automation/build/alpine/3.12.dockerfile b/automation/build/alpine/3.12.dockerfile
new file mode 100644
index 0000000000..2c02417ee6
--- /dev/null
+++ b/automation/build/alpine/3.12.dockerfile
@@ -0,0 +1,52 @@
+FROM alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen build deps
+  apk add argp-standalone && \
+  apk add autoconf && \
+  apk add automake && \
+  apk add bash && \
+  apk add curl && \
+  apk add curl-dev && \
+  apk add dev86 && \
+  apk add gcc  && \
+  apk add clang  && \
+  apk add gettext && \
+  apk add git && \
+  apk add iasl && \
+  apk add libaio-dev && \
+  apk add linux-headers && \
+  apk add make && \
+  apk add musl-dev  && \
+  apk add libc6-compat && \
+  apk add ncurses-dev && \
+  apk add patch  && \
+  apk add python3-dev && \
+  apk add texinfo && \
+  apk add util-linux-dev && \
+  apk add xz-dev && \
+  apk add yajl-dev && \
+  apk add zlib-dev && \
+  \
+  # qemu build deps
+  apk add bison && \
+  apk add flex && \
+  apk add glib-dev && \
+  apk add libattr && \
+  apk add libcap-ng-dev && \
+  apk add pixman-dev && \
+  \
+  # cleanup
+  rm -rf /tmp/* && \
+  rm -f /var/cache/apk/*
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:03 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:03 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56994.99701 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4x-0002Py-QR; Sat, 19 Dec 2020 23:56:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56994.99701; Sat, 19 Dec 2020 23:56:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm4x-0002Pq-NH; Sat, 19 Dec 2020 23:56:03 +0000
Received: by outflank-mailman (input) for mailman id 56994;
 Sat, 19 Dec 2020 23:56:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4x-0002Pj-CQ
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4x-0001Km-Bg
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm4x-0007FW-Aj
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=hylGpVUg5wDb4iHVBFuGXJUhIn/knXd0cIFaJKnr+K4=; b=rn7KcaAP9UCTqeVpEwuW1dNQIH
	PLZtyP8Ll2g5e3Q68t5Z1LJlb7ESE62GUxUwy2M1i1upQtdIZ6Dzz1p4sFGlIoBJ4C6uBwbePpFuh
	4gw3RRxw2dVSx9Zc1JENzHkpaUVUPF89GXANU93sOGuzWtRxzDypvF52lURohxBQCtcg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add alpine linux x86 build jobs
Message-Id: <E1kqm4x-0007FW-Aj@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:03 +0000

commit f6e1d8515d7d69fda131e469576a555f66fde66c
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Fri Nov 20 09:56:25 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add alpine linux x86 build jobs
    
    Allow failure for these jobs. Currently they fail because hvmloader
    doesn't build with musl. The failures don't block the pipeline.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index fa38c39d6a..c48c0f3d66 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -410,6 +410,31 @@ opensuse-leap-gcc-debug:
   variables:
     CONTAINER: suse:opensuse-leap
 
+alpine-3.12-gcc:
+  extends: .gcc-x86-64-build
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-gcc-debug:
+  extends: .gcc-x86-64-build-debug
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-clang:
+  extends: .gcc-x86-64-build
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+alpine-3.12-clang-debug:
+  extends: .gcc-x86-64-build-debug
+  variables:
+    CONTAINER: alpine:3.12
+  allow_failure: true
+
+
 # Arm builds
 
 debian-unstable-gcc-arm64:
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56995.99705 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm58-0002RK-Rw; Sat, 19 Dec 2020 23:56:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56995.99705; Sat, 19 Dec 2020 23:56:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm58-0002RC-Ot; Sat, 19 Dec 2020 23:56:14 +0000
Received: by outflank-mailman (input) for mailman id 56995;
 Sat, 19 Dec 2020 23:56:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm57-0002R3-Fs
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm57-0001Ku-F5
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm57-0007GE-Df
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ICR4hd45ySfNBcOy5xAvc5F9Z1FusRntYZC3J6dA/HY=; b=KXIXKnZ6DwA17Ln3+RqyG8nCC8
	vdmZ3NGXFf5wtahyL5HBS1mjxvOdaqbjtFSmOvuFKy391GQkHimcg06rTVln0FEO725b5vNIZtgYt
	IJYQZZG5i/SSk6JkxJmqZU3xhV/OAM7wxisvDi/waYYjT8E8vXg6UeKQyQAFRr4ZWuWc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add tests artifacts
Message-Id: <E1kqm57-0007GE-Df@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:13 +0000

commit e1681ce44cab50317fba33774b93c56c18fcae64
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:08:20 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add tests artifacts
    
    Some tests (soon to come) will require pre-built binaries to run, such
    as the Linux kernel binary. We don't want to rebuild the Linux kernel
    for each gitlab-ci run: these builds should not be added to the current
    list of build jobs.
    
    Instead, create additional containers that today are built and uploaded
    manually, but could be re-built automatically. The containers build the
    required binarires during the "docker build" step and store them inside
    the container itself.
    
    gitlab-ci will be able to fetch these pre-built binaries during the
    regular test runs, saving cycles.
    
    Add two tests artifacts containers:
    - one to build the Linux kernel ARM64
    - one to create an Alpine Linux ARM64 rootfs for Dom0
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/tests-artifacts/Makefile                | 19 ++++++
 .../tests-artifacts/alpine/3.12-arm64v8.dockerfile | 67 ++++++++++++++++++++++
 .../kernel/5.9.9-arm64v8.dockerfile                | 34 +++++++++++
 3 files changed, 120 insertions(+)

diff --git a/automation/tests-artifacts/Makefile b/automation/tests-artifacts/Makefile
new file mode 100644
index 0000000000..8ca71b78ad
--- /dev/null
+++ b/automation/tests-artifacts/Makefile
@@ -0,0 +1,19 @@
+
+# the base of where these containers will appear
+REGISTRY := registry.gitlab.com/xen-project/xen/tests-artifacts
+CONTAINERS = $(subst .dockerfile,,$(wildcard */*.dockerfile))
+
+help:
+	@echo "Containers to build and export tests artifacts."
+	@echo "To build one run 'make ARTIFACT/VERSION'. Available containers:"
+	@$(foreach file,$(sort $(CONTAINERS)),echo ${file};)
+	@echo "To push container builds, set the env var PUSH"
+
+%: %.dockerfile ## Builds containers
+	docker build -t $(REGISTRY)/$(@D):$(@F) -f $< $(<D)
+	@if [ ! -z $${PUSH+x} ]; then \
+		docker push $(REGISTRY)/$(@D):$(@F); \
+	fi
+
+.PHONY: all
+all: $(CONTAINERS)
diff --git a/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile b/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile
new file mode 100644
index 0000000000..9457009452
--- /dev/null
+++ b/automation/tests-artifacts/alpine/3.12-arm64v8.dockerfile
@@ -0,0 +1,67 @@
+FROM arm64v8/alpine:3.12
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+RUN \
+  # apk
+  apk update && \
+  \
+  # xen runtime deps
+  apk add musl && \
+  apk add openrc && \
+  apk add busybox && \
+  apk add sudo && \
+  apk add dbus && \
+  apk add bash && \
+  apk add python2 && \
+  apk add gettext && \
+  apk add zlib && \
+  apk add ncurses && \
+  apk add texinfo && \
+  apk add yajl && \
+  apk add libaio && \
+  apk add xz-dev && \
+  apk add util-linux && \
+  apk add argp-standalone && \
+  apk add libfdt && \
+  apk add glib && \
+  apk add pixman && \
+  apk add curl && \
+  apk add udev && \
+  \
+  # Xen
+  cd / && \
+  # Minimal ramdisk environment in case of cpio output
+  rc-update add udev && \
+  rc-update add udev-trigger && \
+  rc-update add udev-settle && \
+  rc-update add networking sysinit && \
+  rc-update add loopback sysinit && \
+  rc-update add bootmisc boot && \
+  rc-update add devfs sysinit && \
+  rc-update add dmesg sysinit && \
+  rc-update add hostname boot && \
+  rc-update add hwclock boot && \
+  rc-update add hwdrivers sysinit && \
+  rc-update add killprocs shutdown && \
+  rc-update add modloop sysinit && \
+  rc-update add modules boot && \
+  rc-update add mount-ro shutdown && \
+  rc-update add savecache shutdown && \
+  rc-update add sysctl boot && \
+  rc-update add local default && \
+  cp -a /sbin/init /init && \
+  echo "ttyS0" >> /etc/securetty && \
+  echo "hvc0" >> /etc/securetty && \
+  echo "ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100" >> /etc/inittab && \
+  echo "hvc0::respawn:/sbin/getty -L hvc0 115200 vt100" >> /etc/inittab && \
+  passwd -d "root" root && \
+  \
+  # Create rootfs
+  cd / && \
+  tar cvzf /initrd.tar.gz bin dev etc home init lib mnt opt root sbin usr var
diff --git a/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile b/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile
new file mode 100644
index 0000000000..053d65a345
--- /dev/null
+++ b/automation/tests-artifacts/kernel/5.9.9-arm64v8.dockerfile
@@ -0,0 +1,34 @@
+FROM arm64v8/debian:unstable
+LABEL maintainer.name="The Xen Project" \
+      maintainer.email="xen-devel@lists.xenproject.org"
+
+ENV DEBIAN_FRONTEND=noninteractive
+ENV LINUX_VERSION=5.9.9
+ENV USER root
+
+RUN mkdir /build
+WORKDIR /build
+
+# build depends
+RUN apt-get update && \
+    apt-get --quiet --yes install \
+        build-essential \
+        libssl-dev \
+        bc \
+        curl \
+        flex \
+        bison \
+        && \
+    \
+    # Build the kernel
+    curl -fsSLO https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-"$LINUX_VERSION".tar.xz && \
+    tar xvJf linux-"$LINUX_VERSION".tar.xz && \
+    cd linux-"$LINUX_VERSION" && \
+    make defconfig && \
+    make -j$(nproc) Image.gz && \
+    cp arch/arm64/boot/Image / && \
+    cd /build && \
+    rm -rf linux-"$LINUX_VERSION"* && \
+    apt-get autoremove -y && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists* /tmp/* /var/tmp/*
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56996.99710 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5I-0002Sc-Ti; Sat, 19 Dec 2020 23:56:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56996.99710; Sat, 19 Dec 2020 23:56:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5I-0002SR-QW; Sat, 19 Dec 2020 23:56:24 +0000
Received: by outflank-mailman (input) for mailman id 56996;
 Sat, 19 Dec 2020 23:56:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5H-0002SJ-Jy
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5H-0001L9-JH
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5H-0007Gy-Gz
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/Z8uSOtEulNSDq/jw0eXUagSIuCl1D8R4HYOC4FErT8=; b=3nQNPfJH5LbqH30oM2PYSodIu1
	7dc3s4OtYs5ArVjL/rn8JeGk+epG4qsTgQeQkSenp90Js1pqGh9x5hBLAM5r5n2IKqtIMhUXKtlVm
	+xo/ol8vHvT1/bTBmaJlbtRhUIdLyubHBpb7vl81RLwzI93Ujx+rVEBmkskjJivV+dNY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: make available the tests artifacts to the pipeline
Message-Id: <E1kqm5H-0007Gy-Gz@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:23 +0000

commit 7b532ee54ecc297cd41aaaffd79436ecbfe4188e
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:13:50 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: make available the tests artifacts to the pipeline
    
    In order to make available the pre-built binaries of the
    automation/tests-artifacts containers to the gitlab-ci pipeline we need
    to export them as gitlab artifacts.
    
    To do that, we create two "fake" jobs that simply export the require
    binaries as artifacts and do nothing else.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/build.yaml | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/automation/gitlab-ci/build.yaml b/automation/gitlab-ci/build.yaml
index c48c0f3d66..e5246828f8 100644
--- a/automation/gitlab-ci/build.yaml
+++ b/automation/gitlab-ci/build.yaml
@@ -468,3 +468,29 @@ alpine-3.12-gcc-debug-arm64:
   extends: .gcc-arm64-build-debug
   variables:
     CONTAINER: alpine:3.12-arm64v8
+
+
+# Arm test artifacts
+
+alpine-3.12-arm64-rootfs-export:
+  stage: build
+  image: registry.gitlab.com/xen-project/xen/tests-artifacts/alpine:3.12-arm64v8
+  script:
+    - mkdir binaries && cp /initrd.tar.gz binaries/initrd.tar.gz
+  artifacts:
+    paths:
+      - binaries/initrd.tar.gz
+  tags:
+    - arm64
+
+kernel-5.9.9-arm64-export:
+  stage: build
+  image: registry.gitlab.com/xen-project/xen/tests-artifacts/kernel:5.9.9-arm64v8
+  script:
+    - mkdir binaries && cp /Image binaries/Image
+  artifacts:
+    paths:
+      - binaries/Image
+  tags:
+    - arm64
+
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56997.99713 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5S-0002Tx-Uy; Sat, 19 Dec 2020 23:56:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56997.99713; Sat, 19 Dec 2020 23:56:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5S-0002Tp-S0; Sat, 19 Dec 2020 23:56:34 +0000
Received: by outflank-mailman (input) for mailman id 56997;
 Sat, 19 Dec 2020 23:56:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5R-0002Te-Ns
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5R-0001LI-Mq
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5R-0007HW-LS
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Dujyp9jxM0IOG321i3zbHjzjSKZHO+nUdvjuFuuvcf0=; b=12Jr1NstztNFsiIoZ7XM63gtRe
	mhISuNhGLNc0QucVDLamY9NFSvbZTa/i1Qvp1xAnB8m4I6Ut0aayFKD+G8fBZrx2wf/G7pKkK1II/
	LslW6HfZ07TZ4J5ZpAf0fG8IJMf30XSLGiVjE1wwzY1Vy9TkqflljBnF35CnWaa43S3M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: create an alpine linux arm64 test job
Message-Id: <E1kqm5R-0007HW-LS@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:33 +0000

commit b44eb6daa96b1f3eae21b4fd5c1307519c71275a
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:15:51 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: create an alpine linux arm64 test job
    
    Create a test job that starts Xen and Dom0 on QEMU based on the alpine
    linux rootfs. Use the Linux kernel and rootfs from the tests-artifacts
    containers. Add the Xen tools binaries from the Alpine Linux build job.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml          | 24 ++++++++++
 automation/scripts/build                |  1 +
 automation/scripts/qemu-alpine-arm64.sh | 85 +++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index 35346e3f6e..a291538d68 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -22,6 +22,30 @@ build-each-commit-gcc:
     - /^coverity-tested\/.*/
     - /^stable-.*/
 
+qemu-alpine-arm64-gcc:
+  stage: test
+  image: registry.gitlab.com/xen-project/xen/${CONTAINER}
+  variables:
+    CONTAINER: debian:unstable-arm64v8
+  script:
+    - ./automation/scripts/qemu-alpine-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
+  dependencies:
+    - alpine-3.12-gcc-arm64
+    - alpine-3.12-arm64-rootfs-export
+    - kernel-5.9.9-arm64-export
+  artifacts:
+    paths:
+      - smoke.serial
+      - '*.log'
+    when: always
+  tags:
+    - arm64
+  except:
+    - master
+    - smoke
+    - /^coverity-tested\/.*/
+    - /^stable-.*/
+
 qemu-smoke-arm64-gcc:
   stage: test
   image: registry.gitlab.com/xen-project/xen/${CONTAINER}
diff --git a/automation/scripts/build b/automation/scripts/build
index 959a26d084..d8990c3bf4 100755
--- a/automation/scripts/build
+++ b/automation/scripts/build
@@ -55,6 +55,7 @@ cp xen/.config xen-config
 mkdir binaries
 if [[ "${XEN_TARGET_ARCH}" != "x86_32" ]]; then
     cp xen/xen binaries/xen
+    cp -r dist binaries/
 fi
 
 # Build all the configs we care about
diff --git a/automation/scripts/qemu-alpine-arm64.sh b/automation/scripts/qemu-alpine-arm64.sh
new file mode 100755
index 0000000000..62aae2d4c8
--- /dev/null
+++ b/automation/scripts/qemu-alpine-arm64.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+set -ex
+
+apt-get -qy update
+apt-get -qy install --no-install-recommends qemu-system-aarch64 \
+                                            u-boot-qemu \
+                                            u-boot-tools \
+                                            device-tree-compiler \
+                                            cpio \
+                                            curl
+
+mkdir -p binaries/rootfs
+cd binaries/rootfs
+tar xvzf ../initrd.tar.gz
+mkdir proc
+mkdir run
+mkdir srv
+mkdir sys
+rm var/run
+cp -ar ../dist/install/* .
+echo "#!/bin/bash
+
+export LD_LIBRARY_PATH=/usr/local/lib
+bash /etc/init.d/xencommons start
+
+xl list
+
+" > etc/local.d/xen.start
+chmod +x etc/local.d/xen.start
+echo "rc_verbose=yes" >> etc/rc.conf
+find . |cpio -H newc -o|gzip > ../xen-rootfs.cpio.gz
+cd ../..
+
+# XXX Silly workaround to get the following QEMU command to work
+# QEMU looks for "efi-virtio.rom" even if it is unneeded
+cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
+qemu-system-aarch64 \
+   -machine virtualization=true \
+   -cpu cortex-a57 -machine type=virt \
+   -m 1024 -display none \
+   -machine dumpdtb=binaries/virt-gicv3.dtb
+# XXX disable pl061 to avoid Linux crash
+dtc -I dtb -O dts binaries/virt-gicv3.dtb > binaries/virt-gicv3.dts
+sed 's/compatible = "arm,pl061.*/status = "disabled";/g' binaries/virt-gicv3.dts > binaries/virt-gicv3-edited.dts
+dtc -I dts -O dtb binaries/virt-gicv3-edited.dts > binaries/virt-gicv3.dtb
+
+# ImageBuilder
+echo 'MEMORY_START="0x40000000"
+MEMORY_END="0x80000000"
+
+DEVICE_TREE="virt-gicv3.dtb"
+XEN="xen"
+DOM0_KERNEL="Image"
+DOM0_RAMDISK="xen-rootfs.cpio.gz"
+XEN_CMD="console=dtuart dom0_mem=1024M"
+
+NUM_DOMUS=0
+
+LOAD_CMD="tftpb"
+UBOOT_SOURCE="boot.source"
+UBOOT_SCRIPT="boot.scr"' > binaries/config
+rm -rf imagebuilder
+git clone https://gitlab.com/ViryaOS/imagebuilder
+bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/config
+
+
+# Run the test
+rm -f smoke.serial
+set +e
+echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
+timeout -k 1 480 \
+qemu-system-aarch64 \
+    -machine virtualization=true \
+    -cpu cortex-a57 -machine type=virt \
+    -m 2048 -monitor none -serial stdio \
+    -smp 2 \
+    -no-reboot \
+    -device virtio-net-pci,netdev=n0 \
+    -netdev user,id=n0,tftp=binaries \
+    -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
+
+set -e
+grep -q "Domain-0" smoke.serial || exit 1
+exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56998.99717 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5d-0002VT-0J; Sat, 19 Dec 2020 23:56:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56998.99717; Sat, 19 Dec 2020 23:56:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5c-0002VL-TY; Sat, 19 Dec 2020 23:56:44 +0000
Received: by outflank-mailman (input) for mailman id 56998;
 Sat, 19 Dec 2020 23:56:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5b-0002VD-QG
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5b-0001Lm-PX
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5b-0007IS-Om
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0xOgqamcR4BrYd+l2uUvYwBOwUw5caefefiQiiR8yuA=; b=bUqGOh+tS6LvzOltXd7pWulvDR
	nRiqgUHKhTmHmgyyXSb+89hgt3JpEtWxhEFfOoxUyQSSZYCN2Y2CeA6pTq7FuNy0uFmSnGPMcrYjU
	RbIxY5nI7TUttT8jCXHgilSWKuF3ty2oRiWRt7+MNi7nJteuqwvKNOKmAcQh/toqtIi4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: use the tests-artifacts kernel for qemu-smoke-arm64-gcc
Message-Id: <E1kqm5b-0007IS-Om@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:43 +0000

commit fccaa4d35c78c08eb351fb3692fff51a61a2a4b0
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:22:17 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: use the tests-artifacts kernel for qemu-smoke-arm64-gcc
    
    Use the tests-artifacts kernel, instead of the Debian kernel, for the
    qemu-smoke-arm64-gcc job.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/gitlab-ci/test.yaml         | 1 +
 automation/scripts/qemu-smoke-arm64.sh | 6 ------
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/automation/gitlab-ci/test.yaml b/automation/gitlab-ci/test.yaml
index a291538d68..9448651187 100644
--- a/automation/gitlab-ci/test.yaml
+++ b/automation/gitlab-ci/test.yaml
@@ -55,6 +55,7 @@ qemu-smoke-arm64-gcc:
     - ./automation/scripts/qemu-smoke-arm64.sh 2>&1 | tee qemu-smoke-arm64.log
   dependencies:
     - debian-unstable-gcc-arm64
+    - kernel-5.9.9-arm64-export
   artifacts:
     paths:
       - smoke.serial
diff --git a/automation/scripts/qemu-smoke-arm64.sh b/automation/scripts/qemu-smoke-arm64.sh
index 794c53f887..bdef0717ad 100755
--- a/automation/scripts/qemu-smoke-arm64.sh
+++ b/automation/scripts/qemu-smoke-arm64.sh
@@ -12,12 +12,6 @@ apt-get -qy install --no-install-recommends qemu-system-aarch64 \
                                             busybox-static \
                                             cpio
 
-cd binaries
-apt-get download linux-image-*[0-9]-arm64
-dpkg -i --ignore-depends=initramfs-tools ./linux-image-*arm64.deb || true
-cp /boot/vmlinuz-*arm64 ./Image
-cd ..
-
 # XXX Silly workaround to get the following QEMU command to work
 # QEMU looks for "efi-virtio.rom" even if it is unneeded
 cp /usr/share/qemu/pvh.bin /usr/share/qemu/efi-virtio.rom
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:56:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:56:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.56999.99721 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5n-0002XX-2Q; Sat, 19 Dec 2020 23:56:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 56999.99721; Sat, 19 Dec 2020 23:56:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5m-0002XN-V4; Sat, 19 Dec 2020 23:56:54 +0000
Received: by outflank-mailman (input) for mailman id 56999;
 Sat, 19 Dec 2020 23:56:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5l-0002WT-TW
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5l-0001Lv-Sn
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5l-0007J4-RU
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:56:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=A4cAI561ax/8sc/AMX6bRyvcxpmQIE2caH/svA41ImE=; b=A8zxOUqXFNasufoJXDU/5PkU4D
	BoYPimTfBtPuzbkiBfKV7QwsW1huthM3D2NAtLeIzzMDS6ZjE39Zc4YhcuY7/Yj7cfVyOU467RrAh
	PSj32S5ZbRKHW3xrMRr2OFmZO/J679mueXS7wjDWjnvrprtivJr6SLfnqENmPajAPTWE=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] automation: add domU creation to dom0 alpine linux test
Message-Id: <E1kqm5l-0007J4-RU@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:56:53 +0000

commit 7a3b691a8f3aa7720eecaab0e7bd090aa392885a
Author:     Stefano Stabellini <sstabellini@kernel.org>
AuthorDate: Tue Nov 24 13:33:14 2020 -0800
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Thu Dec 17 14:56:43 2020 -0800

    automation: add domU creation to dom0 alpine linux test
    
    Add a trivial Busybox based domU.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
    Acked-by: Wei Liu <wl@xen.org>
---
 automation/scripts/qemu-alpine-arm64.sh | 47 +++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/automation/scripts/qemu-alpine-arm64.sh b/automation/scripts/qemu-alpine-arm64.sh
index 62aae2d4c8..b43a654270 100755
--- a/automation/scripts/qemu-alpine-arm64.sh
+++ b/automation/scripts/qemu-alpine-arm64.sh
@@ -8,10 +8,36 @@ apt-get -qy install --no-install-recommends qemu-system-aarch64 \
                                             u-boot-tools \
                                             device-tree-compiler \
                                             cpio \
-                                            curl
+                                            curl \
+                                            busybox-static
 
-mkdir -p binaries/rootfs
-cd binaries/rootfs
+# DomU Busybox
+cd binaries
+mkdir -p initrd
+mkdir -p initrd/bin
+mkdir -p initrd/sbin
+mkdir -p initrd/etc
+mkdir -p initrd/dev
+mkdir -p initrd/proc
+mkdir -p initrd/sys
+mkdir -p initrd/lib
+mkdir -p initrd/var
+mkdir -p initrd/mnt
+cp /bin/busybox initrd/bin/busybox
+initrd/bin/busybox --install initrd/bin
+echo "#!/bin/sh
+
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -t devtmpfs devtmpfs /dev
+/bin/sh" > initrd/init
+chmod +x initrd/init
+cd initrd
+find . | cpio --create --format='newc' | gzip > ../initrd.cpio.gz
+cd ..
+
+mkdir -p rootfs
+cd rootfs
 tar xvzf ../initrd.tar.gz
 mkdir proc
 mkdir run
@@ -19,6 +45,15 @@ mkdir srv
 mkdir sys
 rm var/run
 cp -ar ../dist/install/* .
+mv ../initrd.cpio.gz ./root
+cp ../Image ./root
+echo "name=\"test\"
+memory=512
+vcpus=1
+kernel=\"/root/Image\"
+ramdisk=\"/root/initrd.cpio.gz\"
+extra=\"console=hvc0 root=/dev/ram0 rdinit=/bin/sh\"
+" > root/test.cfg
 echo "#!/bin/bash
 
 export LD_LIBRARY_PATH=/usr/local/lib
@@ -26,6 +61,8 @@ bash /etc/init.d/xencommons start
 
 xl list
 
+xl create -c /root/test.cfg
+
 " > etc/local.d/xen.start
 chmod +x etc/local.d/xen.start
 echo "rc_verbose=yes" >> etc/rc.conf
@@ -69,7 +106,7 @@ bash imagebuilder/scripts/uboot-script-gen -t tftp -d binaries/ -c binaries/conf
 rm -f smoke.serial
 set +e
 echo "  virtio scan; dhcp; tftpb 0x40000000 boot.scr; source 0x40000000"| \
-timeout -k 1 480 \
+timeout -k 1 720 \
 qemu-system-aarch64 \
     -machine virtualization=true \
     -cpu cortex-a57 -machine type=virt \
@@ -81,5 +118,5 @@ qemu-system-aarch64 \
     -bios /usr/lib/u-boot/qemu_arm64/u-boot.bin |& tee smoke.serial
 
 set -e
-grep -q "Domain-0" smoke.serial || exit 1
+(grep -q "Domain-0" smoke.serial && grep -q "BusyBox" smoke.serial) || exit 1
 exit 0
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57000.99726 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5x-0002Zn-57; Sat, 19 Dec 2020 23:57:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57000.99726; Sat, 19 Dec 2020 23:57:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm5x-0002Ze-1d; Sat, 19 Dec 2020 23:57:05 +0000
Received: by outflank-mailman (input) for mailman id 57000;
 Sat, 19 Dec 2020 23:57:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5w-0002ZT-0I
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5v-0001MK-Vr
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm5v-0007K6-Ut
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=86GlktUP1LIQyKp9w8ANoEq9E4Vu6Ghrqr+z2cG3j4g=; b=Qix2x29JNJp24RA3PdWyj5TSPX
	1fDz/b5LMg1VTMHL1P7BcBnwzz+Fk8S/e13yNXuOh8pfQH5RA7BosnH/ypwCl3RKvb8yxq6tMW7KQ
	Q8P81xmHSAp4XvVKkHfBAyV6BiJ3J+NvbxVt774n4KanfkBECma0TdLBDlj8A29tAuhc=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: collect library files in an archive
Message-Id: <E1kqm5v-0007K6-Ut@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:03 +0000

commit f301f9a9e84f3cfd18750065f8a3794c8182c7f0
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:17:57 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:17:57 2020 +0100

    lib: collect library files in an archive
    
    In order to (subsequently) drop odd things like CONFIG_NEEDS_LIST_SORT
    just to avoid bloating binaries when only some arch-es and/or
    configurations need generic library routines, combine objects under lib/
    into an archive, which the linker then can pick the necessary objects
    out of.
    
    Note that we can't use thin archives just yet, until we've raised the
    minimum required binutils version suitably.
    
    Note further that --start-group / --end-group get put in place right
    away to allow for symbol resolution across all archives, once we gain
    multuiple ones.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/Rules.mk          | 29 +++++++++++++++++++++++++----
 xen/arch/arm/Makefile |  6 +++---
 xen/arch/x86/Makefile |  8 ++++----
 xen/lib/Makefile      |  3 ++-
 4 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index d5e5eb33de..aba6ca2a90 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -41,12 +41,16 @@ ALL_OBJS-y               += $(BASEDIR)/xsm/built_in.o
 ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
 ALL_OBJS-$(CONFIG_CRYPTO)   += $(BASEDIR)/crypto/built_in.o
 
+ALL_LIBS-y               := $(BASEDIR)/lib/lib.a
+
 # Initialise some variables
+lib-y :=
 targets :=
 CFLAGS-y :=
 AFLAGS-y :=
 
 ALL_OBJS := $(ALL_OBJS-y)
+ALL_LIBS := $(ALL_LIBS-y)
 
 SPECIAL_DATA_SECTIONS := rodata $(foreach a,1 2 4 8 16, \
                                             $(foreach w,1 2 4, \
@@ -60,7 +64,14 @@ include Makefile
 # ---------------------------------------------------------------------------
 
 quiet_cmd_ld = LD      $@
-cmd_ld = $(LD) $(XEN_LDFLAGS) -r -o $@ $(real-prereqs)
+cmd_ld = $(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out %.a,$(real-prereqs)) \
+               --start-group $(filter %.a,$(real-prereqs)) --end-group
+
+# Archive
+# ---------------------------------------------------------------------------
+
+quiet_cmd_ar = AR      $@
+cmd_ar = rm -f $@; $(AR) cPrs $@ $(real-prereqs)
 
 # Objcopy
 # ---------------------------------------------------------------------------
@@ -86,6 +97,10 @@ obj-y    := $(patsubst %/, %/built_in.o, $(obj-y))
 # tell kbuild to descend
 subdir-obj-y := $(filter %/built_in.o, $(obj-y))
 
+# Libraries are always collected in one lib file.
+# Filter out objects already built-in
+lib-y := $(filter-out $(obj-y), $(sort $(lib-y)))
+
 $(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): CFLAGS-y += -DINIT_SECTIONS_ONLY
 
 ifeq ($(CONFIG_COVERAGE),y)
@@ -129,7 +144,7 @@ include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
 c_flags += $(CFLAGS-y)
 a_flags += $(CFLAGS-y) $(AFLAGS-y)
 
-built_in.o: $(obj-y) $(extra-y)
+built_in.o: $(obj-y) $(if $(strip $(lib-y)),lib.a) $(extra-y)
 ifeq ($(strip $(obj-y)),)
 	$(CC) $(c_flags) -c -x c /dev/null -o $@
 else
@@ -140,8 +155,14 @@ else
 endif
 endif
 
+lib.a: $(lib-y) FORCE
+	$(call if_changed,ar)
+
 targets += built_in.o
-targets += $(filter-out $(subdir-obj-y), $(obj-y)) $(extra-y)
+ifneq ($(strip $(lib-y)),)
+targets += lib.a
+endif
+targets += $(filter-out $(subdir-obj-y), $(obj-y) $(lib-y)) $(extra-y)
 targets += $(MAKECMDGOALS)
 
 built_in_bin.o: $(obj-bin-y) $(extra-y)
@@ -155,7 +176,7 @@ endif
 PHONY += FORCE
 FORCE:
 
-%/built_in.o: FORCE
+%/built_in.o %/lib.a: FORCE
 	$(MAKE) -f $(BASEDIR)/Rules.mk -C $* built_in.o
 
 %/built_in_bin.o: FORCE
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index ad2d497c45..512ffdd781 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -90,14 +90,14 @@ endif
 
 ifeq ($(CONFIG_LTO),y)
 # Gather all LTO objects together
-prelink_lto.o: $(ALL_OBJS)
-	$(LD_LTO) -r -o $@ $^
+prelink_lto.o: $(ALL_OBJS) $(ALL_LIBS)
+	$(LD_LTO) -r -o $@ $(filter-out %.a,$^) --start-group $(filter %.a,$^) --end-group
 
 # Link it with all the binary objects
 prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o
 	$(call if_changed,ld)
 else
-prelink.o: $(ALL_OBJS) FORCE
+prelink.o: $(ALL_OBJS) $(ALL_LIBS) FORCE
 	$(call if_changed,ld)
 endif
 
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 9b368632fb..8f2180485b 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -132,8 +132,8 @@ EFI_OBJS-$(XEN_BUILD_EFI) := efi/relocs-dummy.o
 
 ifeq ($(CONFIG_LTO),y)
 # Gather all LTO objects together
-prelink_lto.o: $(ALL_OBJS)
-	$(LD_LTO) -r -o $@ $^
+prelink_lto.o: $(ALL_OBJS) $(ALL_LIBS)
+	$(LD_LTO) -r -o $@ $(filter-out %.a,$^) --start-group $(filter %.a,$^) --end-group
 
 # Link it with all the binary objects
 prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o $(EFI_OBJS-y) FORCE
@@ -142,10 +142,10 @@ prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o $
 prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o FORCE
 	$(call if_changed,ld)
 else
-prelink.o: $(ALL_OBJS) $(EFI_OBJS-y) FORCE
+prelink.o: $(ALL_OBJS) $(ALL_LIBS) $(EFI_OBJS-y) FORCE
 	$(call if_changed,ld)
 
-prelink-efi.o: $(ALL_OBJS) FORCE
+prelink-efi.o: $(ALL_OBJS) $(ALL_LIBS) FORCE
 	$(call if_changed,ld)
 endif
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 53b1da025e..b8814361d6 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,2 +1,3 @@
-obj-y += ctype.o
 obj-$(CONFIG_X86) += x86/
+
+lib-y += ctype.o
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57001.99729 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm67-0002b0-6L; Sat, 19 Dec 2020 23:57:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57001.99729; Sat, 19 Dec 2020 23:57:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm67-0002as-3F; Sat, 19 Dec 2020 23:57:15 +0000
Received: by outflank-mailman (input) for mailman id 57001;
 Sat, 19 Dec 2020 23:57:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm66-0002ak-38
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm66-0001MP-2R
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm66-0007Kz-1d
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ZebcxjXs2mMiKx3nlvoWR3l744ssg8gOqzHMzyhd6Kw=; b=c6d/OkfozIO+KiP3qV/XmZhtVr
	Dg7iWl+N/EIpY+nnfPyc95ecz+VSUHugJMuMJ/Qpruw/kLzCo1SGqohrkEXhrZAQwZyoI22AZEcV7
	turp8AIUUsHTw9B3omj2vD1RdxyV45zoT6uKlUAcwkW7iJ+pEkreo38YbKuE29AJX1F4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move list sorting code
Message-Id: <E1kqm66-0007Kz-1d@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:14 +0000

commit 26dfde919cac720c29d076bc8fd38ad0af1b2abb
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:20:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:20:42 2020 +0100

    lib: move list sorting code
    
    Build the source file always, as by putting it into an archive it still
    won't be linked into final binaries when not needed. This way possible
    build breakage will be easier to notice, and it's more consistent with
    us unconditionally building other library kind of code (e.g. sort() or
    bsearch()).
    
    While moving the source file, take the opportunity and drop the
    pointless EXPORT_SYMBOL() and an unnecessary #include.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/arch/arm/Kconfig   |   4 +-
 xen/common/Kconfig     |   3 -
 xen/common/Makefile    |   1 -
 xen/common/list_sort.c | 157 -------------------------------------------------
 xen/lib/Makefile       |   1 +
 xen/lib/list-sort.c    | 155 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 157 insertions(+), 164 deletions(-)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 41bde2f401..c3eb13ea73 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -56,9 +56,7 @@ config HVM
         def_bool y
 
 config NEW_VGIC
-	bool
-	prompt "Use new VGIC implementation"
-	select NEEDS_LIST_SORT
+	bool "Use new VGIC implementation"
 	---help---
 
 	This is an alternative implementation of the ARM GIC interrupt
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 3e2cf25088..0661328a99 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -66,9 +66,6 @@ config MEM_ACCESS
 config NEEDS_LIBELF
 	bool
 
-config NEEDS_LIST_SORT
-	bool
-
 menu "Speculative hardening"
 
 config SPECULATIVE_HARDEN_ARRAY
diff --git a/xen/common/Makefile b/xen/common/Makefile
index d109f279a4..332e7d667c 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -21,7 +21,6 @@ obj-y += keyhandler.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_KEXEC) += kimage.o
 obj-y += lib.o
-obj-$(CONFIG_NEEDS_LIST_SORT) += list_sort.o
 obj-$(CONFIG_LIVEPATCH) += livepatch.o livepatch_elf.o
 obj-$(CONFIG_MEM_ACCESS) += mem_access.o
 obj-y += memory.o
diff --git a/xen/common/list_sort.c b/xen/common/list_sort.c
deleted file mode 100644
index af2b2f6519..0000000000
--- a/xen/common/list_sort.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * list_sort.c: merge sort implementation for linked lists
- * Copied from the Linux kernel (lib/list_sort.c)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <xen/lib.h>
-#include <xen/list.h>
-
-#define MAX_LIST_LENGTH_BITS 20
-
-/*
- * Returns a list organized in an intermediate format suited
- * to chaining of merge() calls: null-terminated, no reserved or
- * sentinel head node, "prev" links not maintained.
- */
-static struct list_head *merge(void *priv,
-				int (*cmp)(void *priv, struct list_head *a,
-					struct list_head *b),
-				struct list_head *a, struct list_head *b)
-{
-	struct list_head head, *tail = &head;
-
-	while (a && b) {
-		/* if equal, take 'a' -- important for sort stability */
-		if ((*cmp)(priv, a, b) <= 0) {
-			tail->next = a;
-			a = a->next;
-		} else {
-			tail->next = b;
-			b = b->next;
-		}
-		tail = tail->next;
-	}
-	tail->next = a?:b;
-	return head.next;
-}
-
-/*
- * Combine final list merge with restoration of standard doubly-linked
- * list structure.  This approach duplicates code from merge(), but
- * runs faster than the tidier alternatives of either a separate final
- * prev-link restoration pass, or maintaining the prev links
- * throughout.
- */
-static void merge_and_restore_back_links(void *priv,
-				int (*cmp)(void *priv, struct list_head *a,
-					struct list_head *b),
-				struct list_head *head,
-				struct list_head *a, struct list_head *b)
-{
-	struct list_head *tail = head;
-	u8 count = 0;
-
-	while (a && b) {
-		/* if equal, take 'a' -- important for sort stability */
-		if ((*cmp)(priv, a, b) <= 0) {
-			tail->next = a;
-			a->prev = tail;
-			a = a->next;
-		} else {
-			tail->next = b;
-			b->prev = tail;
-			b = b->next;
-		}
-		tail = tail->next;
-	}
-	tail->next = a ? : b;
-
-	do {
-		/*
-		 * In worst cases this loop may run many iterations.
-		 * Continue callbacks to the client even though no
-		 * element comparison is needed, so the client's cmp()
-		 * routine can invoke cond_resched() periodically.
-		 */
-		if (unlikely(!(++count)))
-			(*cmp)(priv, tail->next, tail->next);
-
-		tail->next->prev = tail;
-		tail = tail->next;
-	} while (tail->next);
-
-	tail->next = head;
-	head->prev = tail;
-}
-
-/**
- * list_sort - sort a list
- * @priv: private data, opaque to list_sort(), passed to @cmp
- * @head: the list to sort
- * @cmp: the elements comparison function
- *
- * This function implements "merge sort", which has O(nlog(n))
- * complexity.
- *
- * The comparison function @cmp must return a negative value if @a
- * should sort before @b, and a positive value if @a should sort after
- * @b. If @a and @b are equivalent, and their original relative
- * ordering is to be preserved, @cmp must return 0.
- */
-void list_sort(void *priv, struct list_head *head,
-		int (*cmp)(void *priv, struct list_head *a,
-			struct list_head *b))
-{
-	struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
-						-- last slot is a sentinel */
-	int lev;  /* index into part[] */
-	int max_lev = 0;
-	struct list_head *list;
-
-	if (list_empty(head))
-		return;
-
-	memset(part, 0, sizeof(part));
-
-	head->prev->next = NULL;
-	list = head->next;
-
-	while (list) {
-		struct list_head *cur = list;
-		list = list->next;
-		cur->next = NULL;
-
-		for (lev = 0; part[lev]; lev++) {
-			cur = merge(priv, cmp, part[lev], cur);
-			part[lev] = NULL;
-		}
-		if (lev > max_lev) {
-			if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
-				dprintk(XENLOG_DEBUG,
-					"list too long for efficiency\n");
-				lev--;
-			}
-			max_lev = lev;
-		}
-		part[lev] = cur;
-	}
-
-	for (lev = 0; lev < max_lev; lev++)
-		if (part[lev])
-			list = merge(priv, cmp, part[lev], list);
-
-	merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
-}
-EXPORT_SYMBOL(list_sort);
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index b8814361d6..764f3624b5 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_X86) += x86/
 
 lib-y += ctype.o
+lib-y += list-sort.o
diff --git a/xen/lib/list-sort.c b/xen/lib/list-sort.c
new file mode 100644
index 0000000000..f8d8bbf281
--- /dev/null
+++ b/xen/lib/list-sort.c
@@ -0,0 +1,155 @@
+/*
+ * list_sort.c: merge sort implementation for linked lists
+ * Copied from the Linux kernel (lib/list_sort.c)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/list.h>
+
+#define MAX_LIST_LENGTH_BITS 20
+
+/*
+ * Returns a list organized in an intermediate format suited
+ * to chaining of merge() calls: null-terminated, no reserved or
+ * sentinel head node, "prev" links not maintained.
+ */
+static struct list_head *merge(void *priv,
+				int (*cmp)(void *priv, struct list_head *a,
+					struct list_head *b),
+				struct list_head *a, struct list_head *b)
+{
+	struct list_head head, *tail = &head;
+
+	while (a && b) {
+		/* if equal, take 'a' -- important for sort stability */
+		if ((*cmp)(priv, a, b) <= 0) {
+			tail->next = a;
+			a = a->next;
+		} else {
+			tail->next = b;
+			b = b->next;
+		}
+		tail = tail->next;
+	}
+	tail->next = a?:b;
+	return head.next;
+}
+
+/*
+ * Combine final list merge with restoration of standard doubly-linked
+ * list structure.  This approach duplicates code from merge(), but
+ * runs faster than the tidier alternatives of either a separate final
+ * prev-link restoration pass, or maintaining the prev links
+ * throughout.
+ */
+static void merge_and_restore_back_links(void *priv,
+				int (*cmp)(void *priv, struct list_head *a,
+					struct list_head *b),
+				struct list_head *head,
+				struct list_head *a, struct list_head *b)
+{
+	struct list_head *tail = head;
+	u8 count = 0;
+
+	while (a && b) {
+		/* if equal, take 'a' -- important for sort stability */
+		if ((*cmp)(priv, a, b) <= 0) {
+			tail->next = a;
+			a->prev = tail;
+			a = a->next;
+		} else {
+			tail->next = b;
+			b->prev = tail;
+			b = b->next;
+		}
+		tail = tail->next;
+	}
+	tail->next = a ? : b;
+
+	do {
+		/*
+		 * In worst cases this loop may run many iterations.
+		 * Continue callbacks to the client even though no
+		 * element comparison is needed, so the client's cmp()
+		 * routine can invoke cond_resched() periodically.
+		 */
+		if (unlikely(!(++count)))
+			(*cmp)(priv, tail->next, tail->next);
+
+		tail->next->prev = tail;
+		tail = tail->next;
+	} while (tail->next);
+
+	tail->next = head;
+	head->prev = tail;
+}
+
+/**
+ * list_sort - sort a list
+ * @priv: private data, opaque to list_sort(), passed to @cmp
+ * @head: the list to sort
+ * @cmp: the elements comparison function
+ *
+ * This function implements "merge sort", which has O(nlog(n))
+ * complexity.
+ *
+ * The comparison function @cmp must return a negative value if @a
+ * should sort before @b, and a positive value if @a should sort after
+ * @b. If @a and @b are equivalent, and their original relative
+ * ordering is to be preserved, @cmp must return 0.
+ */
+void list_sort(void *priv, struct list_head *head,
+		int (*cmp)(void *priv, struct list_head *a,
+			struct list_head *b))
+{
+	struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
+						-- last slot is a sentinel */
+	int lev;  /* index into part[] */
+	int max_lev = 0;
+	struct list_head *list;
+
+	if (list_empty(head))
+		return;
+
+	memset(part, 0, sizeof(part));
+
+	head->prev->next = NULL;
+	list = head->next;
+
+	while (list) {
+		struct list_head *cur = list;
+		list = list->next;
+		cur->next = NULL;
+
+		for (lev = 0; part[lev]; lev++) {
+			cur = merge(priv, cmp, part[lev], cur);
+			part[lev] = NULL;
+		}
+		if (lev > max_lev) {
+			if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
+				dprintk(XENLOG_DEBUG,
+					"list too long for efficiency\n");
+				lev--;
+			}
+			max_lev = lev;
+		}
+		part[lev] = cur;
+	}
+
+	for (lev = 0; lev < max_lev; lev++)
+		if (part[lev])
+			list = merge(priv, cmp, part[lev], list);
+
+	merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
+}
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57002.99733 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6H-0002cJ-7p; Sat, 19 Dec 2020 23:57:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57002.99733; Sat, 19 Dec 2020 23:57:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6H-0002cB-4r; Sat, 19 Dec 2020 23:57:25 +0000
Received: by outflank-mailman (input) for mailman id 57002;
 Sat, 19 Dec 2020 23:57:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6G-0002c3-64
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6G-0001Mb-5O
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6G-0007Uw-4U
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8iBodWeRpKBl6IfmIM6+2Rvt1KaIQoJs17MLzs/qeDg=; b=sZc5/ByLHZr3Gk8rJKWX/c9H+l
	4to6d/MKNKNSbTlVFiJkaMZ3YsUVrDxoAl7+8zGGMxSCxLL0zNLff19EW664Q11/psZmsokUSzN5i
	+URYgathkPpgs+wcRhpkW6a9nUrpYwmnOhTQyZGp3ge9peRTYCrAt7qv1gnEUIx/iyBs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move parse_size_and_unit()
Message-Id: <E1kqm6G-0007Uw-4U@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:24 +0000

commit 65fdf25768deba4e8bea751773f2ec4f7ff67ea5
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:21:25 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:21:25 2020 +0100

    lib: move parse_size_and_unit()
    
    ... into its own CU, to build it into an archive.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/lib.c     | 39 ---------------------------------------
 xen/lib/Makefile     |  1 +
 xen/lib/parse-size.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 39 deletions(-)

diff --git a/xen/common/lib.c b/xen/common/lib.c
index a224efa8f6..6cfa332142 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -423,45 +423,6 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 #endif
 }
 
-unsigned long long parse_size_and_unit(const char *s, const char **ps)
-{
-    unsigned long long ret;
-    const char *s1;
-
-    ret = simple_strtoull(s, &s1, 0);
-
-    switch ( *s1 )
-    {
-    case 'T': case 't':
-        ret <<= 10;
-        /* fallthrough */
-    case 'G': case 'g':
-        ret <<= 10;
-        /* fallthrough */
-    case 'M': case 'm':
-        ret <<= 10;
-        /* fallthrough */
-    case 'K': case 'k':
-        ret <<= 10;
-        /* fallthrough */
-    case 'B': case 'b':
-        s1++;
-        break;
-    case '%':
-        if ( ps )
-            break;
-        /* fallthrough */
-    default:
-        ret <<= 10; /* default to kB */
-        break;
-    }
-
-    if ( ps != NULL )
-        *ps = s1;
-
-    return ret;
-}
-
 typedef void (*ctor_func_t)(void);
 extern const ctor_func_t __ctors_start[], __ctors_end[];
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 764f3624b5..99f857540c 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_X86) += x86/
 
 lib-y += ctype.o
 lib-y += list-sort.o
+lib-y += parse-size.o
diff --git a/xen/lib/parse-size.c b/xen/lib/parse-size.c
new file mode 100644
index 0000000000..ec980cadff
--- /dev/null
+++ b/xen/lib/parse-size.c
@@ -0,0 +1,50 @@
+#include <xen/lib.h>
+
+unsigned long long parse_size_and_unit(const char *s, const char **ps)
+{
+    unsigned long long ret;
+    const char *s1;
+
+    ret = simple_strtoull(s, &s1, 0);
+
+    switch ( *s1 )
+    {
+    case 'T': case 't':
+        ret <<= 10;
+        /* fallthrough */
+    case 'G': case 'g':
+        ret <<= 10;
+        /* fallthrough */
+    case 'M': case 'm':
+        ret <<= 10;
+        /* fallthrough */
+    case 'K': case 'k':
+        ret <<= 10;
+        /* fallthrough */
+    case 'B': case 'b':
+        s1++;
+        break;
+    case '%':
+        if ( ps )
+            break;
+        /* fallthrough */
+    default:
+        ret <<= 10; /* default to kB */
+        break;
+    }
+
+    if ( ps != NULL )
+        *ps = s1;
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57003.99737 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6R-0002da-9H; Sat, 19 Dec 2020 23:57:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57003.99737; Sat, 19 Dec 2020 23:57:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6R-0002dS-6L; Sat, 19 Dec 2020 23:57:35 +0000
Received: by outflank-mailman (input) for mailman id 57003;
 Sat, 19 Dec 2020 23:57:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6Q-0002dJ-9B
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6Q-0001Ml-8S
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6Q-0007VX-7d
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cprW6vR9gTEHEi+5FmV5uOzQevNzBshpfYfWGN5+bAg=; b=NaIYz3L2NYjchz2ADix1ENU1e9
	QfHTqlg3Km0ukNg23JAoPRfNYJbT+f1MvA5cX+Toghgr24+XJYfvTCryNc1xYEd0IZio50rjuz6N9
	W0Mr/6X15VRo3jvWwKdZsCxhv5HRedDWRKAAx1/FlmNRCLm85EvWBCMo9Yp0XwQY8uTQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move init_constructors()
Message-Id: <E1kqm6Q-0007VX-7d@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:34 +0000

commit 3b1d8eb4744d210abcd1c033bf07d20345b926ba
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:22:10 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:22:10 2020 +0100

    lib: move init_constructors()
    
    ... into its own CU, for being unrelated to other things in
    common/lib.c.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/lib.c | 14 --------------
 xen/lib/Makefile |  1 +
 xen/lib/ctors.c  | 25 +++++++++++++++++++++++++
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/xen/common/lib.c b/xen/common/lib.c
index 6cfa332142..f5ca179a0a 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -1,6 +1,5 @@
 #include <xen/lib.h>
 #include <xen/types.h>
-#include <xen/init.h>
 #include <asm/byteorder.h>
 
 /*
@@ -423,19 +422,6 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 #endif
 }
 
-typedef void (*ctor_func_t)(void);
-extern const ctor_func_t __ctors_start[], __ctors_end[];
-
-void __init init_constructors(void)
-{
-    const ctor_func_t *f;
-    for ( f = __ctors_start; f < __ctors_end; ++f )
-        (*f)();
-
-    /* Putting this here seems as good (or bad) as any other place. */
-    BUILD_BUG_ON(sizeof(size_t) != sizeof(ssize_t));
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 99f857540c..72c72fffec 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_X86) += x86/
 
+lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
diff --git a/xen/lib/ctors.c b/xen/lib/ctors.c
new file mode 100644
index 0000000000..5bdc591cd5
--- /dev/null
+++ b/xen/lib/ctors.c
@@ -0,0 +1,25 @@
+#include <xen/init.h>
+#include <xen/lib.h>
+
+typedef void (*ctor_func_t)(void);
+extern const ctor_func_t __ctors_start[], __ctors_end[];
+
+void __init init_constructors(void)
+{
+    const ctor_func_t *f;
+    for ( f = __ctors_start; f < __ctors_end; ++f )
+        (*f)();
+
+    /* Putting this here seems as good (or bad) as any other place. */
+    BUILD_BUG_ON(sizeof(size_t) != sizeof(ssize_t));
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57004.99741 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6b-0002fO-Cd; Sat, 19 Dec 2020 23:57:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57004.99741; Sat, 19 Dec 2020 23:57:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6b-0002fF-9F; Sat, 19 Dec 2020 23:57:45 +0000
Received: by outflank-mailman (input) for mailman id 57004;
 Sat, 19 Dec 2020 23:57:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6a-0002f5-Bw
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6a-0001NE-BF
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6a-0007WD-AT
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Xg7ktI/nYa2ufiXqglYeXtcMmelet9eVsUf8Es2FHdI=; b=Gvy5luUc3P2FpY0yXtjOtbWMHt
	To31JOGaWrHAFSxqs7lMybAUNNrYAQpv8PnCdXa64R91aVtLMclt7DpOyIzYlojo9JHiiYVmUS1aH
	W7Ug0OQzooJTSqKyfeZSuoA9Oy4yDWInouRP6ahHmMXT3Cy/kLbtZltVPPHHz4RP7wYk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move rbtree code
Message-Id: <E1kqm6a-0007WD-AT@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:44 +0000

commit c54212261dc3305429344fe1d1cb298b30830155
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:22:54 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:22:54 2020 +0100

    lib: move rbtree code
    
    Build this code into an archive, which results in not linking it into
    x86 final binaries. This saves about 1.5k of dead code.
    
    While moving the source file, take the opportunity and drop the
    pointless EXPORT_SYMBOL() and an instance of trailing whitespace.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile |   1 -
 xen/common/rbtree.c | 577 ----------------------------------------------------
 xen/lib/Makefile    |   1 +
 xen/lib/rbtree.c    | 570 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 571 insertions(+), 578 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index 332e7d667c..d65c9fe9cb 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -33,7 +33,6 @@ obj-y += preempt.o
 obj-y += random.o
 obj-y += rangeset.o
 obj-y += radix-tree.o
-obj-y += rbtree.o
 obj-y += rcupdate.o
 obj-y += rwlock.o
 obj-y += shutdown.o
diff --git a/xen/common/rbtree.c b/xen/common/rbtree.c
deleted file mode 100644
index 9f5498a89d..0000000000
--- a/xen/common/rbtree.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
-  Red Black Trees
-  (C) 1999  Andrea Arcangeli <andrea@suse.de>
-  (C) 2002  David Woodhouse <dwmw2@infradead.org>
-  (C) 2012  Michel Lespinasse <walken@google.com>
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-  linux/lib/rbtree.c
-*/
-
-#include <xen/types.h>
-#include <xen/rbtree.h>
-
-/*
- * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree 
- *
- *  1) A node is either red or black
- *  2) The root is black
- *  3) All leaves (NULL) are black
- *  4) Both children of every red node are black
- *  5) Every simple path from root to leaves contains the same number
- *     of black nodes.
- *
- *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
- *  consecutive red nodes in a path and every red node is therefore followed by
- *  a black. So if B is the number of black nodes on every simple path (as per
- *  5), then the longest possible path due to 4 is 2B.
- *
- *  We shall indicate color with case, where black nodes are uppercase and red
- *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
- *  parentheses and have some accompanying text comment.
- */
-
-#define		RB_RED		0
-#define		RB_BLACK	1
-
-#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
-
-#define __rb_color(pc)     ((pc) & 1)
-#define __rb_is_black(pc)  __rb_color(pc)
-#define __rb_is_red(pc)    (!__rb_color(pc))
-#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
-#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
-#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
-
-static inline void rb_set_black(struct rb_node *rb)
-{
-	rb->__rb_parent_color |= RB_BLACK;
-}
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
-}
-
-static inline void rb_set_parent_color(struct rb_node *rb,
-				      struct rb_node *p, int color)
-{
-	rb->__rb_parent_color = (unsigned long)p | color;
-}
-
-static inline struct rb_node *rb_red_parent(struct rb_node *red)
-{
-	return (struct rb_node *)red->__rb_parent_color;
-}
-
-static inline void
-__rb_change_child(struct rb_node *old, struct rb_node *new,
-		  struct rb_node *parent, struct rb_root *root)
-{
-	if (parent) {
-		if (parent->rb_left == old)
-			parent->rb_left = new;
-		else
-			parent->rb_right = new;
-	} else
-		root->rb_node = new;
-}
-
-/*
- * Helper function for rotations:
- * - old's parent and color get assigned to new
- * - old gets assigned new as a parent and 'color' as a color.
- */
-static inline void
-__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
-			struct rb_root *root, int color)
-{
-	struct rb_node *parent = rb_parent(old);
-	new->__rb_parent_color = old->__rb_parent_color;
-	rb_set_parent_color(old, new, color);
-	__rb_change_child(old, new, parent, root);
-}
-
-void rb_insert_color(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
-
-	while (true) {
-		/*
-		 * Loop invariant: node is red
-		 *
-		 * If there is a black parent, we are done.
-		 * Otherwise, take some corrective action as we don't
-		 * want a red root or two consecutive red nodes.
-		 */
-		if (!parent) {
-			rb_set_parent_color(node, NULL, RB_BLACK);
-			break;
-		} else if (rb_is_black(parent))
-			break;
-
-		gparent = rb_red_parent(parent);
-
-		tmp = gparent->rb_right;
-		if (parent != tmp) {    /* parent == gparent->rb_left */
-			if (tmp && rb_is_red(tmp)) {
-				/*
-				 * Case 1 - color flips
-				 *
-				 *       G            g
-				 *      / \          / \
-				 *     p   u  -->   P   U
-				 *    /            /
-				 *   n            n
-				 *
-				 * However, since g's parent might be red, and
-				 * 4) does not allow this, we need to recurse
-				 * at g.
-				 */
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-				rb_set_parent_color(parent, gparent, RB_BLACK);
-				node = gparent;
-				parent = rb_parent(node);
-				rb_set_parent_color(node, parent, RB_RED);
-				continue;
-			}
-
-			tmp = parent->rb_right;
-			if (node == tmp) {
-				/*
-				 * Case 2 - left rotate at parent
-				 *
-				 *      G             G
-				 *     / \           / \
-				 *    p   U  -->    n   U
-				 *     \           /
-				 *      n         p
-				 *
-				 * This still leaves us in violation of 4), the
-				 * continuation into Case 3 will fix that.
-				 */
-				parent->rb_right = tmp = node->rb_left;
-				node->rb_left = parent;
-				if (tmp)
-					rb_set_parent_color(tmp, parent,
-							    RB_BLACK);
-				rb_set_parent_color(parent, node, RB_RED);
-				parent = node;
-				tmp = node->rb_right;
-			}
-
-			/*
-			 * Case 3 - right rotate at gparent
-			 *
-			 *        G           P
-			 *       / \         / \
-			 *      p   U  -->  n   g
-			 *     /                 \
-			 *    n                   U
-			 */
-			gparent->rb_left = tmp;  /* == parent->rb_right */
-			parent->rb_right = gparent;
-			if (tmp)
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
-			break;
-		} else {
-			tmp = gparent->rb_left;
-			if (tmp && rb_is_red(tmp)) {
-				/* Case 1 - color flips */
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-				rb_set_parent_color(parent, gparent, RB_BLACK);
-				node = gparent;
-				parent = rb_parent(node);
-				rb_set_parent_color(node, parent, RB_RED);
-				continue;
-			}
-
-			tmp = parent->rb_left;
-			if (node == tmp) {
-				/* Case 2 - right rotate at parent */
-				parent->rb_left = tmp = node->rb_right;
-				node->rb_right = parent;
-				if (tmp)
-					rb_set_parent_color(tmp, parent,
-							    RB_BLACK);
-				rb_set_parent_color(parent, node, RB_RED);
-				parent = node;
-				tmp = node->rb_left;
-			}
-
-			/* Case 3 - left rotate at gparent */
-			gparent->rb_right = tmp;  /* == parent->rb_left */
-			parent->rb_left = gparent;
-			if (tmp)
-				rb_set_parent_color(tmp, gparent, RB_BLACK);
-			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
-			break;
-		}
-	}
-}
-EXPORT_SYMBOL(rb_insert_color);
-
-static void __rb_erase_color(struct rb_node *parent, struct rb_root *root)
-{
-	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
-
-	while (true) {
-		/*
-		 * Loop invariants:
-		 * - node is black (or NULL on first iteration)
-		 * - node is not the root (parent is not NULL)
-		 * - All leaf paths going through parent and node have a
-		 *   black node count that is 1 lower than other leaf paths.
-		 */
-		sibling = parent->rb_right;
-		if (node != sibling) {  /* node == parent->rb_left */
-			if (rb_is_red(sibling)) {
-				/*
-				 * Case 1 - left rotate at parent
-				 *
-				 *     P               S
-				 *    / \             / \
-				 *   N   s    -->    p   Sr
-				 *      / \         / \
-				 *     Sl  Sr      N   Sl
-				 */
-				parent->rb_right = tmp1 = sibling->rb_left;
-				sibling->rb_left = parent;
-				rb_set_parent_color(tmp1, parent, RB_BLACK);
-				__rb_rotate_set_parents(parent, sibling, root,
-							RB_RED);
-				sibling = tmp1;
-			}
-			tmp1 = sibling->rb_right;
-			if (!tmp1 || rb_is_black(tmp1)) {
-				tmp2 = sibling->rb_left;
-				if (!tmp2 || rb_is_black(tmp2)) {
-					/*
-					* Case 2 - sibling color flip
-					* (p could be either color here)
-					*
-					*    (p)           (p)
-					*    / \           / \
-					*   N   S    -->  N   s
-					*      / \           / \
-					*     Sl  Sr        Sl  Sr
-					*
-					* This leaves us violating 5) which
-					* can be fixed by flipping p to black
-					* if it was red, or by recursing at p.
-					* p is red when coming from Case 1.
-					*/
-					rb_set_parent_color(sibling, parent,
-							    RB_RED);
-					if (rb_is_red(parent))
-						rb_set_black(parent);
-					else {
-						node = parent;
-						parent = rb_parent(node);
-						if (parent)
-							continue;
-					}
-					break;
-				}
-				/*
-				 * Case 3 - right rotate at sibling
-				 * (p could be either color here)
-				 *
-				 *   (p)           (p)
-				 *   / \           / \
-				 *  N   S    -->  N   Sl
-				 *     / \             \
-				 *    sl  Sr            s
-				 *                       \
-				 *                        Sr
-				 */
-				sibling->rb_left = tmp1 = tmp2->rb_right;
-				tmp2->rb_right = sibling;
-				parent->rb_right = tmp2;
-				if (tmp1)
-					rb_set_parent_color(tmp1, sibling,
-							    RB_BLACK);
-				tmp1 = sibling;
-				sibling = tmp2;
-			}
-			/*
-			 * Case 4 - left rotate at parent + color flips
-			 * (p and sl could be either color here.
-			 *  After rotation, p becomes black, s acquires
-			 *  p's color, and sl keeps its color)
-			 *
-			 *      (p)             (s)
-			 *      / \             / \
-			 *     N   S     -->   P   Sr
-			 *        / \         / \
-			 *      (sl) sr      N  (sl)
-			 */
-			parent->rb_right = tmp2 = sibling->rb_left;
-			sibling->rb_left = parent;
-			rb_set_parent_color(tmp1, sibling, RB_BLACK);
-			if (tmp2)
-				rb_set_parent(tmp2, parent);
-			__rb_rotate_set_parents(parent, sibling, root,
-						RB_BLACK);
-			break;
-		} else {
-			sibling = parent->rb_left;
-			if (rb_is_red(sibling)) {
-				/* Case 1 - right rotate at parent */
-				parent->rb_left = tmp1 = sibling->rb_right;
-				sibling->rb_right = parent;
-				rb_set_parent_color(tmp1, parent, RB_BLACK);
-				__rb_rotate_set_parents(parent, sibling, root,
-							RB_RED);
-				sibling = tmp1;
-			}
-			tmp1 = sibling->rb_left;
-			if (!tmp1 || rb_is_black(tmp1)) {
-				tmp2 = sibling->rb_right;
-				if (!tmp2 || rb_is_black(tmp2)) {
-					/* Case 2 - sibling color flip */
-					rb_set_parent_color(sibling, parent,
-							    RB_RED);
-					if (rb_is_red(parent))
-						rb_set_black(parent);
-					else {
-						node = parent;
-						parent = rb_parent(node);
-						if (parent)
-							continue;
-					}
-					break;
-				}
-				/* Case 3 - right rotate at sibling */
-				sibling->rb_right = tmp1 = tmp2->rb_left;
-				tmp2->rb_left = sibling;
-				parent->rb_left = tmp2;
-				if (tmp1)
-					rb_set_parent_color(tmp1, sibling,
-							    RB_BLACK);
-				tmp1 = sibling;
-				sibling = tmp2;
-			}
-			/* Case 4 - left rotate at parent + color flips */
-			parent->rb_left = tmp2 = sibling->rb_right;
-			sibling->rb_right = parent;
-			rb_set_parent_color(tmp1, sibling, RB_BLACK);
-			if (tmp2)
-				rb_set_parent(tmp2, parent);
-			__rb_rotate_set_parents(parent, sibling, root,
-						RB_BLACK);
-			break;
-		}
-	}
-}
-
-void rb_erase(struct rb_node *node, struct rb_root *root)
-{
-	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
-	struct rb_node *parent, *rebalance;
-	unsigned long pc;
-
-	if (!tmp) {
-		/*
-		 * Case 1: node to erase has no more than 1 child (easy!)
-		 *
-		 * Note that if there is one child it must be red due to 5)
-		 * and node must be black due to 4). We adjust colors locally
-		 * so as to bypass __rb_erase_color() later on.
-		 */
-		pc = node->__rb_parent_color;
-		parent = __rb_parent(pc);
-		__rb_change_child(node, child, parent, root);
-		if (child) {
-			child->__rb_parent_color = pc;
-			rebalance = NULL;
-		} else
-			rebalance = __rb_is_black(pc) ? parent : NULL;
-	} else if (!child) {
-		/* Still case 1, but this time the child is node->rb_left */
-		tmp->__rb_parent_color = pc = node->__rb_parent_color;
-		parent = __rb_parent(pc);
-		__rb_change_child(node, tmp, parent, root);
-		rebalance = NULL;
-	} else {
-		struct rb_node *successor = child, *child2;
-		tmp = child->rb_left;
-		if (!tmp) {
-			/*
-			 * Case 2: node's successor is its right child
-			 *
-			 *    (n)          (s)
-			 *    / \          / \
-			 *  (x) (s)  ->  (x) (c)
-			 *        \
-			 *        (c)
-			 */
-			parent = child;
-			child2 = child->rb_right;
-		} else {
-			/*
-			 * Case 3: node's successor is leftmost under
-			 * node's right child subtree
-			 *
-			 *    (n)          (s)
-			 *    / \          / \
-			 *  (x) (y)  ->  (x) (y)
-			 *      /            /
-			 *    (p)          (p)
-			 *    /            /
-			 *  (s)          (c)
-			 *    \
-			 *    (c)
-			 */
-			do {
-				parent = successor;
-				successor = tmp;
-				tmp = tmp->rb_left;
-			} while (tmp);
-			parent->rb_left = child2 = successor->rb_right;
-			successor->rb_right = child;
-			rb_set_parent(child, successor);
-		}
-
-		successor->rb_left = tmp = node->rb_left;
-		rb_set_parent(tmp, successor);
-
-		pc = node->__rb_parent_color;
-		tmp = __rb_parent(pc);
-		__rb_change_child(node, successor, tmp, root);
-		if (child2) {
-			successor->__rb_parent_color = pc;
-			rb_set_parent_color(child2, parent, RB_BLACK);
-			rebalance = NULL;
-		} else {
-			unsigned long pc2 = successor->__rb_parent_color;
-			successor->__rb_parent_color = pc;
-			rebalance = __rb_is_black(pc2) ? parent : NULL;
-		}
-	}
-
-	if (rebalance)
-		__rb_erase_color(rebalance, root);
-}
-EXPORT_SYMBOL(rb_erase);
-
-/*
- * This function returns the first node (in sort order) of the tree.
- */
-struct rb_node *rb_first(const struct rb_root *root)
-{
-	struct rb_node	*n;
-
-	n = root->rb_node;
-	if (!n)
-		return NULL;
-	while (n->rb_left)
-		n = n->rb_left;
-	return n;
-}
-EXPORT_SYMBOL(rb_first);
-
-struct rb_node *rb_last(const struct rb_root *root)
-{
-	struct rb_node	*n;
-
-	n = root->rb_node;
-	if (!n)
-		return NULL;
-	while (n->rb_right)
-		n = n->rb_right;
-	return n;
-}
-EXPORT_SYMBOL(rb_last);
-
-struct rb_node *rb_next(const struct rb_node *node)
-{
-	struct rb_node *parent;
-
-	if (RB_EMPTY_NODE(node))
-		return NULL;
-
-	/*
-	 * If we have a right-hand child, go down and then left as far
-	 * as we can.
-	 */
-	if (node->rb_right) {
-		node = node->rb_right;
-		while (node->rb_left)
-			node=node->rb_left;
-		return (struct rb_node *)node;
-	}
-
-	/*
-	 * No right-hand children. Everything down and left is smaller than us,
-	 * so any 'next' node must be in the general direction of our parent.
-	 * Go up the tree; any time the ancestor is a right-hand child of its
-	 * parent, keep going up. First time it's a left-hand child of its
-	 * parent, said parent is our 'next' node.
-	 */
-	while ((parent = rb_parent(node)) && node == parent->rb_right)
-		node = parent;
-
-	return parent;
-}
-EXPORT_SYMBOL(rb_next);
-
-struct rb_node *rb_prev(const struct rb_node *node)
-{
-	struct rb_node *parent;
-
-	if (RB_EMPTY_NODE(node))
-		return NULL;
-
-	/*
-	 * If we have a left-hand child, go down and then right as far
-	 * as we can.
-	 */
-	if (node->rb_left) {
-		node = node->rb_left;
-		while (node->rb_right)
-			node=node->rb_right;
-		return (struct rb_node *)node;
-	}
-
-	/*
-	 * No left-hand children. Go up till we find an ancestor which
-	 * is a right-hand child of its parent
-	 */
-	while ((parent = rb_parent(node)) && node == parent->rb_left)
-		node = parent;
-
-	return parent;
-}
-EXPORT_SYMBOL(rb_prev);
-
-void rb_replace_node(struct rb_node *victim, struct rb_node *new,
-		     struct rb_root *root)
-{
-	struct rb_node *parent = rb_parent(victim);
-
-	/* Set the surrounding nodes to point to the replacement */
-	__rb_change_child(victim, new, parent, root);
-	if (victim->rb_left)
-		rb_set_parent(victim->rb_left, new);
-	if (victim->rb_right)
-		rb_set_parent(victim->rb_right, new);
-
-	/* Copy the pointers/colour from the victim to the replacement */
-	*new = *victim;
-}
-EXPORT_SYMBOL(rb_replace_node);
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 72c72fffec..b0fe8c72ac 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -4,3 +4,4 @@ lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
+lib-y += rbtree.o
diff --git a/xen/lib/rbtree.c b/xen/lib/rbtree.c
new file mode 100644
index 0000000000..95e045d524
--- /dev/null
+++ b/xen/lib/rbtree.c
@@ -0,0 +1,570 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  (C) 2002  David Woodhouse <dwmw2@infradead.org>
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/lib/rbtree.c
+*/
+
+#include <xen/types.h>
+#include <xen/rbtree.h>
+
+/*
+ * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
+ *
+ *  1) A node is either red or black
+ *  2) The root is black
+ *  3) All leaves (NULL) are black
+ *  4) Both children of every red node are black
+ *  5) Every simple path from root to leaves contains the same number
+ *     of black nodes.
+ *
+ *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
+ *  consecutive red nodes in a path and every red node is therefore followed by
+ *  a black. So if B is the number of black nodes on every simple path (as per
+ *  5), then the longest possible path due to 4 is 2B.
+ *
+ *  We shall indicate color with case, where black nodes are uppercase and red
+ *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
+ *  parentheses and have some accompanying text comment.
+ */
+
+#define		RB_RED		0
+#define		RB_BLACK	1
+
+#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc)     ((pc) & 1)
+#define __rb_is_black(pc)  __rb_color(pc)
+#define __rb_is_red(pc)    (!__rb_color(pc))
+#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
+
+static inline void rb_set_black(struct rb_node *rb)
+{
+	rb->__rb_parent_color |= RB_BLACK;
+}
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+
+static inline void rb_set_parent_color(struct rb_node *rb,
+				      struct rb_node *p, int color)
+{
+	rb->__rb_parent_color = (unsigned long)p | color;
+}
+
+static inline struct rb_node *rb_red_parent(struct rb_node *red)
+{
+	return (struct rb_node *)red->__rb_parent_color;
+}
+
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+		  struct rb_node *parent, struct rb_root *root)
+{
+	if (parent) {
+		if (parent->rb_left == old)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else
+		root->rb_node = new;
+}
+
+/*
+ * Helper function for rotations:
+ * - old's parent and color get assigned to new
+ * - old gets assigned new as a parent and 'color' as a color.
+ */
+static inline void
+__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
+			struct rb_root *root, int color)
+{
+	struct rb_node *parent = rb_parent(old);
+	new->__rb_parent_color = old->__rb_parent_color;
+	rb_set_parent_color(old, new, color);
+	__rb_change_child(old, new, parent, root);
+}
+
+void rb_insert_color(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
+
+	while (true) {
+		/*
+		 * Loop invariant: node is red
+		 *
+		 * If there is a black parent, we are done.
+		 * Otherwise, take some corrective action as we don't
+		 * want a red root or two consecutive red nodes.
+		 */
+		if (!parent) {
+			rb_set_parent_color(node, NULL, RB_BLACK);
+			break;
+		} else if (rb_is_black(parent))
+			break;
+
+		gparent = rb_red_parent(parent);
+
+		tmp = gparent->rb_right;
+		if (parent != tmp) {    /* parent == gparent->rb_left */
+			if (tmp && rb_is_red(tmp)) {
+				/*
+				 * Case 1 - color flips
+				 *
+				 *       G            g
+				 *      / \          / \
+				 *     p   u  -->   P   U
+				 *    /            /
+				 *   n            n
+				 *
+				 * However, since g's parent might be red, and
+				 * 4) does not allow this, we need to recurse
+				 * at g.
+				 */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_right;
+			if (node == tmp) {
+				/*
+				 * Case 2 - left rotate at parent
+				 *
+				 *      G             G
+				 *     / \           / \
+				 *    p   U  -->    n   U
+				 *     \           /
+				 *      n         p
+				 *
+				 * This still leaves us in violation of 4), the
+				 * continuation into Case 3 will fix that.
+				 */
+				parent->rb_right = tmp = node->rb_left;
+				node->rb_left = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				parent = node;
+				tmp = node->rb_right;
+			}
+
+			/*
+			 * Case 3 - right rotate at gparent
+			 *
+			 *        G           P
+			 *       / \         / \
+			 *      p   U  -->  n   g
+			 *     /                 \
+			 *    n                   U
+			 */
+			gparent->rb_left = tmp;  /* == parent->rb_right */
+			parent->rb_right = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			break;
+		} else {
+			tmp = gparent->rb_left;
+			if (tmp && rb_is_red(tmp)) {
+				/* Case 1 - color flips */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_left;
+			if (node == tmp) {
+				/* Case 2 - right rotate at parent */
+				parent->rb_left = tmp = node->rb_right;
+				node->rb_right = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				parent = node;
+				tmp = node->rb_left;
+			}
+
+			/* Case 3 - left rotate at gparent */
+			gparent->rb_right = tmp;  /* == parent->rb_left */
+			parent->rb_left = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			break;
+		}
+	}
+}
+
+static void __rb_erase_color(struct rb_node *parent, struct rb_root *root)
+{
+	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
+
+	while (true) {
+		/*
+		 * Loop invariants:
+		 * - node is black (or NULL on first iteration)
+		 * - node is not the root (parent is not NULL)
+		 * - All leaf paths going through parent and node have a
+		 *   black node count that is 1 lower than other leaf paths.
+		 */
+		sibling = parent->rb_right;
+		if (node != sibling) {  /* node == parent->rb_left */
+			if (rb_is_red(sibling)) {
+				/*
+				 * Case 1 - left rotate at parent
+				 *
+				 *     P               S
+				 *    / \             / \
+				 *   N   s    -->    p   Sr
+				 *      / \         / \
+				 *     Sl  Sr      N   Sl
+				 */
+				parent->rb_right = tmp1 = sibling->rb_left;
+				sibling->rb_left = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_right;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_left;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/*
+					* Case 2 - sibling color flip
+					* (p could be either color here)
+					*
+					*    (p)           (p)
+					*    / \           / \
+					*   N   S    -->  N   s
+					*      / \           / \
+					*     Sl  Sr        Sl  Sr
+					*
+					* This leaves us violating 5) which
+					* can be fixed by flipping p to black
+					* if it was red, or by recursing at p.
+					* p is red when coming from Case 1.
+					*/
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/*
+				 * Case 3 - right rotate at sibling
+				 * (p could be either color here)
+				 *
+				 *   (p)           (p)
+				 *   / \           / \
+				 *  N   S    -->  N   Sl
+				 *     / \             \
+				 *    sl  Sr            s
+				 *                       \
+				 *                        Sr
+				 */
+				sibling->rb_left = tmp1 = tmp2->rb_right;
+				tmp2->rb_right = sibling;
+				parent->rb_right = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/*
+			 * Case 4 - left rotate at parent + color flips
+			 * (p and sl could be either color here.
+			 *  After rotation, p becomes black, s acquires
+			 *  p's color, and sl keeps its color)
+			 *
+			 *      (p)             (s)
+			 *      / \             / \
+			 *     N   S     -->   P   Sr
+			 *        / \         / \
+			 *      (sl) sr      N  (sl)
+			 */
+			parent->rb_right = tmp2 = sibling->rb_left;
+			sibling->rb_left = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			break;
+		} else {
+			sibling = parent->rb_left;
+			if (rb_is_red(sibling)) {
+				/* Case 1 - right rotate at parent */
+				parent->rb_left = tmp1 = sibling->rb_right;
+				sibling->rb_right = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_left;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_right;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/* Case 2 - sibling color flip */
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/* Case 3 - right rotate at sibling */
+				sibling->rb_right = tmp1 = tmp2->rb_left;
+				tmp2->rb_left = sibling;
+				parent->rb_left = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/* Case 4 - left rotate at parent + color flips */
+			parent->rb_left = tmp2 = sibling->rb_right;
+			sibling->rb_right = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			break;
+		}
+	}
+}
+
+void rb_erase(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+	struct rb_node *parent, *rebalance;
+	unsigned long pc;
+
+	if (!tmp) {
+		/*
+		 * Case 1: node to erase has no more than 1 child (easy!)
+		 *
+		 * Note that if there is one child it must be red due to 5)
+		 * and node must be black due to 4). We adjust colors locally
+		 * so as to bypass __rb_erase_color() later on.
+		 */
+		pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, child, parent, root);
+		if (child) {
+			child->__rb_parent_color = pc;
+			rebalance = NULL;
+		} else
+			rebalance = __rb_is_black(pc) ? parent : NULL;
+	} else if (!child) {
+		/* Still case 1, but this time the child is node->rb_left */
+		tmp->__rb_parent_color = pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, tmp, parent, root);
+		rebalance = NULL;
+	} else {
+		struct rb_node *successor = child, *child2;
+		tmp = child->rb_left;
+		if (!tmp) {
+			/*
+			 * Case 2: node's successor is its right child
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (s)  ->  (x) (c)
+			 *        \
+			 *        (c)
+			 */
+			parent = child;
+			child2 = child->rb_right;
+		} else {
+			/*
+			 * Case 3: node's successor is leftmost under
+			 * node's right child subtree
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (y)  ->  (x) (y)
+			 *      /            /
+			 *    (p)          (p)
+			 *    /            /
+			 *  (s)          (c)
+			 *    \
+			 *    (c)
+			 */
+			do {
+				parent = successor;
+				successor = tmp;
+				tmp = tmp->rb_left;
+			} while (tmp);
+			parent->rb_left = child2 = successor->rb_right;
+			successor->rb_right = child;
+			rb_set_parent(child, successor);
+		}
+
+		successor->rb_left = tmp = node->rb_left;
+		rb_set_parent(tmp, successor);
+
+		pc = node->__rb_parent_color;
+		tmp = __rb_parent(pc);
+		__rb_change_child(node, successor, tmp, root);
+		if (child2) {
+			successor->__rb_parent_color = pc;
+			rb_set_parent_color(child2, parent, RB_BLACK);
+			rebalance = NULL;
+		} else {
+			unsigned long pc2 = successor->__rb_parent_color;
+			successor->__rb_parent_color = pc;
+			rebalance = __rb_is_black(pc2) ? parent : NULL;
+		}
+	}
+
+	if (rebalance)
+		__rb_erase_color(rebalance, root);
+}
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct rb_node *rb_first(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_left)
+		n = n->rb_left;
+	return n;
+}
+
+struct rb_node *rb_last(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_right)
+		n = n->rb_right;
+	return n;
+}
+
+struct rb_node *rb_next(const struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (RB_EMPTY_NODE(node))
+		return NULL;
+
+	/*
+	 * If we have a right-hand child, go down and then left as far
+	 * as we can.
+	 */
+	if (node->rb_right) {
+		node = node->rb_right;
+		while (node->rb_left)
+			node=node->rb_left;
+		return (struct rb_node *)node;
+	}
+
+	/*
+	 * No right-hand children. Everything down and left is smaller than us,
+	 * so any 'next' node must be in the general direction of our parent.
+	 * Go up the tree; any time the ancestor is a right-hand child of its
+	 * parent, keep going up. First time it's a left-hand child of its
+	 * parent, said parent is our 'next' node.
+	 */
+	while ((parent = rb_parent(node)) && node == parent->rb_right)
+		node = parent;
+
+	return parent;
+}
+
+struct rb_node *rb_prev(const struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (RB_EMPTY_NODE(node))
+		return NULL;
+
+	/*
+	 * If we have a left-hand child, go down and then right as far
+	 * as we can.
+	 */
+	if (node->rb_left) {
+		node = node->rb_left;
+		while (node->rb_right)
+			node=node->rb_right;
+		return (struct rb_node *)node;
+	}
+
+	/*
+	 * No left-hand children. Go up till we find an ancestor which
+	 * is a right-hand child of its parent
+	 */
+	while ((parent = rb_parent(node)) && node == parent->rb_left)
+		node = parent;
+
+	return parent;
+}
+
+void rb_replace_node(struct rb_node *victim, struct rb_node *new,
+		     struct rb_root *root)
+{
+	struct rb_node *parent = rb_parent(victim);
+
+	/* Set the surrounding nodes to point to the replacement */
+	__rb_change_child(victim, new, parent, root);
+	if (victim->rb_left)
+		rb_set_parent(victim->rb_left, new);
+	if (victim->rb_right)
+		rb_set_parent(victim->rb_right, new);
+
+	/* Copy the pointers/colour from the victim to the replacement */
+	*new = *victim;
+}
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:57:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:57:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57005.99744 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6l-0002gh-FH; Sat, 19 Dec 2020 23:57:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57005.99744; Sat, 19 Dec 2020 23:57:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6l-0002gZ-CP; Sat, 19 Dec 2020 23:57:55 +0000
Received: by outflank-mailman (input) for mailman id 57005;
 Sat, 19 Dec 2020 23:57:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6k-0002gT-Ef
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6k-0001NK-E2
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6k-0007Wv-DI
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:57:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Lw3Uc93cwG8ssRJT2l5C1kZkeOOkdqBWZojB8wssLLw=; b=3AkbUIBwXF2Ev0drkxa11PpIfv
	Q1/FfQFjtuIs4SslEzgbTfqUp5l5aa57D1D0P/cTW2/1q8RLvHwLcxqtsskZcVcgySI+22Zjuywb/
	A5YK9sJ/pE/vYH+rXk8HDqmKcxGJhqPymu/TNg97LcaTlY18Unwv8xcOKntd3S15q5Xg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move bsearch code
Message-Id: <E1kqm6k-0007Wv-DI@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:57:54 +0000

commit 7c3af561acb70ddd16069b9c9cab3ce503a10987
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:23:42 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:23:42 2020 +0100

    lib: move bsearch code
    
    Convert this code to an inline function (backed by an instance in an
    archive in case the compiler decides against inlining), which results
    in not having it in x86 final binaries. This saves a little bit of dead
    code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile        |  1 -
 xen/common/bsearch.c       | 51 ----------------------------------------------
 xen/include/xen/compiler.h |  1 +
 xen/include/xen/lib.h      | 42 +++++++++++++++++++++++++++++++++++++-
 xen/lib/Makefile           |  1 +
 xen/lib/bsearch.c          | 13 ++++++++++++
 6 files changed, 56 insertions(+), 53 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index d65c9fe9cb..e8ce23acea 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -1,6 +1,5 @@
 obj-$(CONFIG_ARGO) += argo.o
 obj-y += bitmap.o
-obj-y += bsearch.o
 obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
 obj-$(CONFIG_CORE_PARKING) += core_parking.o
 obj-y += cpu.o
diff --git a/xen/common/bsearch.c b/xen/common/bsearch.c
deleted file mode 100644
index 7090930aab..0000000000
--- a/xen/common/bsearch.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * A generic implementation of binary search for the Linux kernel
- *
- * Copyright (C) 2008-2009 Ksplice, Inc.
- * Author: Tim Abbott <tabbott@ksplice.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2.
- */
-
-#include <xen/lib.h>
-
-/*
- * bsearch - binary search an array of elements
- * @key: pointer to item being searched for
- * @base: pointer to first element to search
- * @num: number of elements
- * @size: size of each element
- * @cmp: pointer to comparison function
- *
- * This function does a binary search on the given array.  The
- * contents of the array should already be in ascending sorted order
- * under the provided comparison function.
- *
- * Note that the key need not have the same type as the elements in
- * the array, e.g. key could be a string and the comparison function
- * could compare the string with the struct's name field.  However, if
- * the key and elements in the array are of the same type, you can use
- * the same comparison function for both sort() and bsearch().
- */
-void *bsearch(const void *key, const void *base, size_t num, size_t size,
-	      int (*cmp)(const void *key, const void *elt))
-{
-	size_t start = 0, end = num;
-	int result;
-
-	while (start < end) {
-		size_t mid = start + (end - start) / 2;
-
-		result = cmp(key, base + mid * size);
-		if (result < 0)
-			end = mid;
-		else if (result > 0)
-			start = mid + 1;
-		else
-			return (void *)base + mid * size;
-	}
-
-	return NULL;
-}
diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h
index 676c6ea1b0..e643e69128 100644
--- a/xen/include/xen/compiler.h
+++ b/xen/include/xen/compiler.h
@@ -12,6 +12,7 @@
 
 #define inline        __inline__
 #define always_inline __inline__ __attribute__ ((__always_inline__))
+#define gnu_inline    __inline__ __attribute__ ((__gnu_inline__))
 #define noinline      __attribute__((__noinline__))
 
 #define noreturn      __attribute__((__noreturn__))
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index a9679c913d..48429b69b8 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -204,8 +204,48 @@ void dump_execstate(struct cpu_user_regs *);
 
 void init_constructors(void);
 
+/*
+ * bsearch - binary search an array of elements
+ * @key: pointer to item being searched for
+ * @base: pointer to first element to search
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp: pointer to comparison function
+ *
+ * This function does a binary search on the given array.  The
+ * contents of the array should already be in ascending sorted order
+ * under the provided comparison function.
+ *
+ * Note that the key need not have the same type as the elements in
+ * the array, e.g. key could be a string and the comparison function
+ * could compare the string with the struct's name field.  However, if
+ * the key and elements in the array are of the same type, you can use
+ * the same comparison function for both sort() and bsearch().
+ */
+#ifndef BSEARCH_IMPLEMENTATION
+extern gnu_inline
+#endif
 void *bsearch(const void *key, const void *base, size_t num, size_t size,
-              int (*cmp)(const void *key, const void *elt));
+              int (*cmp)(const void *key, const void *elt))
+{
+    size_t start = 0, end = num;
+    int result;
+
+    while ( start < end )
+    {
+        size_t mid = start + (end - start) / 2;
+
+        result = cmp(key, base + mid * size);
+        if ( result < 0 )
+            end = mid;
+        else if ( result > 0 )
+            start = mid + 1;
+        else
+            return (void *)base + mid * size;
+    }
+
+    return NULL;
+}
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index b0fe8c72ac..f12dab7a73 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_X86) += x86/
 
+lib-y += bsearch.o
 lib-y += ctors.o
 lib-y += ctype.o
 lib-y += list-sort.o
diff --git a/xen/lib/bsearch.c b/xen/lib/bsearch.c
new file mode 100644
index 0000000000..149f7feafd
--- /dev/null
+++ b/xen/lib/bsearch.c
@@ -0,0 +1,13 @@
+/*
+ * A generic implementation of binary search for the Linux kernel
+ *
+ * Copyright (C) 2008-2009 Ksplice, Inc.
+ * Author: Tim Abbott <tabbott@ksplice.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2.
+ */
+
+#define BSEARCH_IMPLEMENTATION
+#include <xen/lib.h>
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:58:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:58:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57006.99749 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6v-0002i3-HW; Sat, 19 Dec 2020 23:58:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57006.99749; Sat, 19 Dec 2020 23:58:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm6v-0002ht-E5; Sat, 19 Dec 2020 23:58:05 +0000
Received: by outflank-mailman (input) for mailman id 57006;
 Sat, 19 Dec 2020 23:58:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6u-0002hl-HZ
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6u-0001Nt-Gw
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm6u-0007Xd-G9
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=DP10Ur22HzyMfoVSOjyPsxub/s1mnQcxu80Pkdno2YM=; b=1B//4SanH4Tjb5ICha9R92rLIz
	c8XxbfVWopbeOicBC/2rjyciTvfoC3zRs0jtMsOj0shb85XONGY22kpxHmEk8ekp0UFK2D68NyPhQ
	6lRTCS/kRmzgWDUCj+tSzAZsgFgjLpwpb9Z77pgpUCT458+m6wx0XLRPq5kPiROwN+5M=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] lib: move sort code
Message-Id: <E1kqm6u-0007Xd-G9@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:58:04 +0000

commit f772b592b75d3144174d4c645b916f2718d9cce5
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:25:40 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:25:40 2020 +0100

    lib: move sort code
    
    Build this code into an archive, partly paralleling bsearch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Acked-by: Wei Liu <wl@xen.org>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
---
 xen/common/Makefile |  1 -
 xen/common/sort.c   | 82 -----------------------------------------------------
 xen/lib/Makefile    |  1 +
 xen/lib/sort.c      | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 83 deletions(-)

diff --git a/xen/common/Makefile b/xen/common/Makefile
index e8ce23acea..7a4e652b57 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -36,7 +36,6 @@ obj-y += rcupdate.o
 obj-y += rwlock.o
 obj-y += shutdown.o
 obj-y += softirq.o
-obj-y += sort.o
 obj-y += smp.o
 obj-y += spinlock.o
 obj-y += stop_machine.o
diff --git a/xen/common/sort.c b/xen/common/sort.c
deleted file mode 100644
index 7b7544bbc2..0000000000
--- a/xen/common/sort.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
- *
- * Jan 23 2005  Matt Mackall <mpm@selenic.com>
- */
-
-#include <xen/types.h>
-
-static void u32_swap(void *a, void *b, int size)
-{
-    u32 t = *(u32 *)a;
-    *(u32 *)a = *(u32 *)b;
-    *(u32 *)b = t;
-}
-
-static void generic_swap(void *a, void *b, int size)
-{
-    char t;
-
-    do {
-        t = *(char *)a;
-        *(char *)a++ = *(char *)b;
-        *(char *)b++ = t;
-    } while ( --size > 0 );
-}
-
-/*
- * sort - sort an array of elements
- * @base: pointer to data to sort
- * @num: number of elements
- * @size: size of each element
- * @cmp: pointer to comparison function
- * @swap: pointer to swap function or NULL
- *
- * This function does a heapsort on the given array. You may provide a
- * swap function optimized to your element type.
- *
- * Sorting time is O(n log n) both on average and worst-case. While
- * qsort is about 20% faster on average, it suffers from exploitable
- * O(n*n) worst-case behavior and extra memory requirements that make
- * it less suitable for kernel use.
- */
-
-void sort(void *base, size_t num, size_t size,
-          int (*cmp)(const void *, const void *),
-          void (*swap)(void *, void *, int size))
-{
-    /* pre-scale counters for performance */
-    int i = (num/2 - 1) * size, n = num * size, c, r;
-
-    if (!swap)
-        swap = (size == 4 ? u32_swap : generic_swap);
-
-    /* heapify */
-    for ( ; i >= 0; i -= size )
-    {
-        for ( r = i; r * 2 + size < n; r  = c )
-        {
-            c = r * 2 + size;
-            if ( (c < n - size) && (cmp(base + c, base + c + size) < 0) )
-                c += size;
-            if ( cmp(base + r, base + c) >= 0 )
-                break;
-            swap(base + r, base + c, size);
-        }
-    }
-
-    /* sort */
-    for ( i = n - size; i >= 0; i -= size )
-    {
-        swap(base, base + i, size);
-        for ( r = 0; r * 2 + size < i; r = c )
-        {
-            c = r * 2 + size;
-            if ( (c < i - size) && (cmp(base + c, base + c + size) < 0) )
-                c += size;
-            if ( cmp(base + r, base + c) >= 0 )
-                break;
-            swap(base + r, base + c, size);
-        }
-    }
-}
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index f12dab7a73..42cf7a1164 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -6,3 +6,4 @@ lib-y += ctype.o
 lib-y += list-sort.o
 lib-y += parse-size.o
 lib-y += rbtree.o
+lib-y += sort.o
diff --git a/xen/lib/sort.c b/xen/lib/sort.c
new file mode 100644
index 0000000000..ee983d0bc3
--- /dev/null
+++ b/xen/lib/sort.c
@@ -0,0 +1,82 @@
+/*
+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
+ *
+ * Jan 23 2005  Matt Mackall <mpm@selenic.com>
+ */
+
+#include <xen/types.h>
+
+static void u32_swap(void *a, void *b, int size)
+{
+    u32 t = *(u32 *)a;
+    *(u32 *)a = *(u32 *)b;
+    *(u32 *)b = t;
+}
+
+static void generic_swap(void *a, void *b, int size)
+{
+    char t;
+
+    do {
+        t = *(char *)a;
+        *(char *)a++ = *(char *)b;
+        *(char *)b++ = t;
+    } while ( --size > 0 );
+}
+
+/*
+ * sort - sort an array of elements
+ * @base: pointer to data to sort
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp: pointer to comparison function
+ * @swap: pointer to swap function or NULL
+ *
+ * This function does a heapsort on the given array. You may provide a
+ * swap function optimized to your element type.
+ *
+ * Sorting time is O(n log n) both on average and worst-case. While
+ * qsort is about 20% faster on average, it suffers from exploitable
+ * O(n*n) worst-case behavior and extra memory requirements that make
+ * it less suitable for kernel use.
+ */
+
+void sort(void *base, size_t num, size_t size,
+          int (*cmp)(const void *, const void *),
+          void (*swap)(void *, void *, int size))
+{
+    /* pre-scale counters for performance */
+    int i = (num / 2 - 1) * size, n = num * size, c, r;
+
+    if ( !swap )
+        swap = (size == 4 ? u32_swap : generic_swap);
+
+    /* heapify */
+    for ( ; i >= 0; i -= size )
+    {
+        for ( r = i; r * 2 + size < n; r  = c )
+        {
+            c = r * 2 + size;
+            if ( (c < n - size) && (cmp(base + c, base + c + size) < 0) )
+                c += size;
+            if ( cmp(base + r, base + c) >= 0 )
+                break;
+            swap(base + r, base + c, size);
+        }
+    }
+
+    /* sort */
+    for ( i = n - size; i >= 0; i -= size )
+    {
+        swap(base, base + i, size);
+        for ( r = 0; r * 2 + size < i; r = c )
+        {
+            c = r * 2 + size;
+            if ( (c < i - size) && (cmp(base + c, base + c + size) < 0) )
+                c += size;
+            if ( cmp(base + r, base + c) >= 0 )
+                break;
+            swap(base + r, base + c, size);
+        }
+    }
+}
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:58:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:58:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57009.99768 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm76-0002lp-1c; Sat, 19 Dec 2020 23:58:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57009.99768; Sat, 19 Dec 2020 23:58:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm75-0002lh-Uh; Sat, 19 Dec 2020 23:58:15 +0000
Received: by outflank-mailman (input) for mailman id 57009;
 Sat, 19 Dec 2020 23:58:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm74-0002lH-KM
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm74-0001O9-Jm
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm74-0007Yi-J4
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=SsRHLqptAX8eZY6qYRHhwV5ZIE8YYRtLffVluD4h0eA=; b=po/qA476iHmS2yZhpVqck05lgb
	y1jdVC28OZw64XSjHLmLlIr/27FCWuVAcdN1iLnqwXyP6wNuZgrfUIHRx7sSCXp85IK0SDPRZ9DGQ
	iUis/6sXH7Ufl217nbN+Tpc9n3a8i4Pq/mlHiro5n6pw9ERBe/U+80fzjg5fRRDkH4YA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/p2m: tidy p2m_add_foreign() a little
Message-Id: <E1kqm74-0007Yi-J4@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:58:14 +0000

commit 173ae325026bd161ae5eecebda28dab2c7a80668
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:28:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:28:30 2020 +0100

    x86/p2m: tidy p2m_add_foreign() a little
    
    Drop a bogus ASSERT() - we don't typically assert incoming domain
    pointers to be non-NULL, and there's no particular reason to do so here.
    
    Replace the open-coded DOMID_SELF check by use of
    rcu_lock_remote_domain_by_id(), at the same time covering the request
    being made with the current domain's actual ID.
    
    Move the "both domains same" check into just the path where it really
    is meaningful.
    
    Swap the order of the two puts, such that
    - the p2m lock isn't needlessly held across put_page(),
    - a separate put_page() on an error path can be avoided,
    - they're inverse to the order of the respective gets.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm/p2m.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index cd0812db18..4caa666def 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -2565,9 +2565,6 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     int rc;
     struct domain *fdom;
 
-    ASSERT(tdom);
-    if ( foreigndom == DOMID_SELF )
-        return -EINVAL;
     /*
      * hvm fixme: until support is added to p2m teardown code to cleanup any
      * foreign entries, limit this to hardware domain only.
@@ -2578,13 +2575,15 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     if ( foreigndom == DOMID_XEN )
         fdom = rcu_lock_domain(dom_xen);
     else
-        fdom = rcu_lock_domain_by_id(foreigndom);
-    if ( fdom == NULL )
-        return -ESRCH;
+    {
+        rc = rcu_lock_remote_domain_by_id(foreigndom, &fdom);
+        if ( rc )
+            return rc;
 
-    rc = -EINVAL;
-    if ( tdom == fdom )
-        goto out;
+        rc = -EINVAL;
+        if ( tdom == fdom )
+            goto out;
+    }
 
     rc = xsm_map_gmfn_foreign(XSM_TARGET, tdom, fdom);
     if ( rc )
@@ -2598,10 +2597,8 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     if ( !page ||
          !p2m_is_ram(p2mt) || p2m_is_shared(p2mt) || p2m_is_hole(p2mt) )
     {
-        if ( page )
-            put_page(page);
         rc = -EINVAL;
-        goto out;
+        goto put_one;
     }
     mfn = page_to_mfn(page);
 
@@ -2630,8 +2627,6 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
                  gpfn, mfn_x(mfn), fgfn, tdom->domain_id, fdom->domain_id);
 
  put_both:
-    put_page(page);
-
     /*
      * This put_gfn for the above get_gfn for prev_mfn.  We must do this
      * after set_foreign_p2m_entry so another cpu doesn't populate the gpfn
@@ -2639,9 +2634,13 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
      */
     put_gfn(tdom, gpfn);
 
-out:
+ put_one:
+    put_page(page);
+
+ out:
     if ( fdom )
         rcu_unlock_domain(fdom);
+
     return rc;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:58:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:58:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57011.99774 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm7G-0002p7-4J; Sat, 19 Dec 2020 23:58:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57011.99774; Sat, 19 Dec 2020 23:58:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm7G-0002oz-08; Sat, 19 Dec 2020 23:58:26 +0000
Received: by outflank-mailman (input) for mailman id 57011;
 Sat, 19 Dec 2020 23:58:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7E-0002of-Na
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7E-0001OL-Mx
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7E-0007Zl-ME
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=xyZEveSocFWIbecbuLdfao5xtHSdI7YGg7D6ap89DX4=; b=SqthNAhaotfCVd3TdgiFs32A+Y
	EbF6T1fHstgxErq/aAvjh6CwF4ABDzNzaZVVrvYB6MtGWcVq1ooTeTkZs1f6YRxkOoE008jTn0/2w
	853w0aKHeKmY5zegbCGSVp2DYpq2eKBM521Z1vz0lJrMv9fQxqGMzUFbIfxLNembQSTg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/mm: p2m_add_foreign() is HVM-only
Message-Id: <E1kqm7E-0007Zl-ME@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:58:24 +0000

commit 8009c33b5179536e2ecce54462fe4cd069060f77
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Dec 18 13:29:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Dec 18 13:29:14 2020 +0100

    x86/mm: p2m_add_foreign() is HVM-only
    
    This is the case also for xenmem_add_to_physmap_one(), as is it's only
    caller of the function. Move the latter next to p2m_add_foreign(),
    allowing it one to become static at the same time. While moving, adjust
    indentation of the body of the main switch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 -----------------------------------------
 xen/arch/x86/mm/p2m.c     | 124 ++++++++++++++++++++++++++++++++++++++++++++--
 xen/include/asm-x86/p2m.h |   4 --
 3 files changed, 120 insertions(+), 120 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 723cc1070f..79acf20c4e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,7 +118,6 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
-#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -142,10 +141,7 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
-
-#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
-#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4591,114 +4587,6 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-        case XENMAPSPACE_shared_info:
-            if ( idx == 0 )
-                mfn = virt_to_mfn(d->shared_info);
-            break;
-        case XENMAPSPACE_grant_table:
-            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-            if ( rc )
-                return rc;
-            break;
-        case XENMAPSPACE_gmfn:
-        {
-            p2m_type_t p2mt;
-
-            gfn = idx;
-            mfn = get_gfn_unshare(d, gfn, &p2mt);
-            /* If the page is still shared, exit early */
-            if ( p2m_is_shared(p2mt) )
-            {
-                put_gfn(d, gfn);
-                return -ENOMEM;
-            }
-            page = get_page_from_mfn(mfn, d);
-            if ( unlikely(!page) )
-                mfn = INVALID_MFN;
-            break;
-        }
-        case XENMAPSPACE_gmfn_foreign:
-            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-        default:
-            break;
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4caa666def..487959b121 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,6 +27,7 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
+#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -42,6 +43,10 @@
 
 #include "mm-locks.h"
 
+/* Override macro from asm/page.h to make work with mfn_t */
+#undef virt_to_mfn
+#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
+
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2540,6 +2545,8 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
+#ifdef CONFIG_HVM
+
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2556,8 +2563,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreigndom)
+static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                           unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2644,7 +2651,115 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-#ifdef CONFIG_HVM
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+    case XENMAPSPACE_shared_info:
+        if ( idx == 0 )
+            mfn = virt_to_mfn(d->shared_info);
+        break;
+
+    case XENMAPSPACE_grant_table:
+        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+        if ( rc )
+            return rc;
+        break;
+
+    case XENMAPSPACE_gmfn:
+    {
+        p2m_type_t p2mt;
+
+        gfn = idx;
+        mfn = get_gfn_unshare(d, gfn, &p2mt);
+        /* If the page is still shared, exit early */
+        if ( p2m_is_shared(p2mt) )
+        {
+            put_gfn(d, gfn);
+            return -ENOMEM;
+        }
+        page = get_page_from_mfn(mfn, d);
+        if ( unlikely(!page) )
+            mfn = INVALID_MFN;
+        break;
+    }
+
+    case XENMAPSPACE_gmfn_foreign:
+        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2797,7 +2912,8 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-#endif
+
+#endif /* CONFIG_HVM */
 
 /*
  * Local variables:
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 8d6fd1aa01..6447696bcd 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,10 +661,6 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
-/* Add foreign mapping to the guest's p2m table. */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreign_domid);
-
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sat Dec 19 23:58:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sat, 19 Dec 2020 23:58:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57013.99775 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm7Q-0002rk-6b; Sat, 19 Dec 2020 23:58:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57013.99775; Sat, 19 Dec 2020 23:58:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kqm7Q-0002rc-3g; Sat, 19 Dec 2020 23:58:36 +0000
Received: by outflank-mailman (input) for mailman id 57013;
 Sat, 19 Dec 2020 23:58:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7O-0002rS-Rc
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7O-0001OX-Q4
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kqm7O-0007aP-PL
 for xen-changelog@lists.xenproject.org; Sat, 19 Dec 2020 23:58:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Ggj9owtkK9BotTfZHmvxTRgdexjEIO7gjFUovU4kTwY=; b=fQhr7fLlPpgXiP3moVOnbAMS8X
	F6+QRUozTBqcvViCEJYvNpbpftf37/RdUpxmwfTIThSy1zXUWqq2eQelwgSt9j+mHMXzihTbC4OW1
	YlLMWzDGD/3JSqYYFOi0vaVZhet0dwaUZjuBFU4Pkak3Tm0EP2t+/pB19o6g8ygj8VX0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] Revert "x86/mm: p2m_add_foreign() is HVM-only"
Message-Id: <E1kqm7O-0007aP-PL@xenbits.xenproject.org>
Date: Sat, 19 Dec 2020 23:58:34 +0000

commit 357db96a66e47e609c3b14768f1062e13eedbd93
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Fri Dec 18 17:53:13 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Fri Dec 18 17:53:13 2020 +0000

    Revert "x86/mm: p2m_add_foreign() is HVM-only"
    
    This reverts commit 8009c33b5179536e2ecce54462fe4cd069060f77.  It breaks the
    PV-Shim build.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 +++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/p2m.c     | 124 ++--------------------------------------------
 xen/include/asm-x86/p2m.h |   4 ++
 3 files changed, 120 insertions(+), 120 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 79acf20c4e..723cc1070f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,6 +118,7 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
+#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -141,7 +142,10 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
+
+#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
+#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4587,6 +4591,114 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+        case XENMAPSPACE_shared_info:
+            if ( idx == 0 )
+                mfn = virt_to_mfn(d->shared_info);
+            break;
+        case XENMAPSPACE_grant_table:
+            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+            if ( rc )
+                return rc;
+            break;
+        case XENMAPSPACE_gmfn:
+        {
+            p2m_type_t p2mt;
+
+            gfn = idx;
+            mfn = get_gfn_unshare(d, gfn, &p2mt);
+            /* If the page is still shared, exit early */
+            if ( p2m_is_shared(p2mt) )
+            {
+                put_gfn(d, gfn);
+                return -ENOMEM;
+            }
+            page = get_page_from_mfn(mfn, d);
+            if ( unlikely(!page) )
+                mfn = INVALID_MFN;
+            break;
+        }
+        case XENMAPSPACE_gmfn_foreign:
+            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+        default:
+            break;
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 487959b121..4caa666def 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,7 +27,6 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
-#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -43,10 +42,6 @@
 
 #include "mm-locks.h"
 
-/* Override macro from asm/page.h to make work with mfn_t */
-#undef virt_to_mfn
-#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
-
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2545,8 +2540,6 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
-#ifdef CONFIG_HVM
-
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2563,8 +2556,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                           unsigned long gpfn, domid_t foreigndom)
+int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                    unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2651,115 +2644,7 @@ static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-    case XENMAPSPACE_shared_info:
-        if ( idx == 0 )
-            mfn = virt_to_mfn(d->shared_info);
-        break;
-
-    case XENMAPSPACE_grant_table:
-        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-        if ( rc )
-            return rc;
-        break;
-
-    case XENMAPSPACE_gmfn:
-    {
-        p2m_type_t p2mt;
-
-        gfn = idx;
-        mfn = get_gfn_unshare(d, gfn, &p2mt);
-        /* If the page is still shared, exit early */
-        if ( p2m_is_shared(p2mt) )
-        {
-            put_gfn(d, gfn);
-            return -ENOMEM;
-        }
-        page = get_page_from_mfn(mfn, d);
-        if ( unlikely(!page) )
-            mfn = INVALID_MFN;
-        break;
-    }
-
-    case XENMAPSPACE_gmfn_foreign:
-        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
+#ifdef CONFIG_HVM
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2912,8 +2797,7 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-
-#endif /* CONFIG_HVM */
+#endif
 
 /*
  * Local variables:
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 6447696bcd..8d6fd1aa01 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,6 +661,10 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
+/* Add foreign mapping to the guest's p2m table. */
+int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                    unsigned long gpfn, domid_t foreign_domid);
+
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:10 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:10 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57209.100016 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5yp-0006SR-Pe; Sun, 20 Dec 2020 21:11:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57209.100016; Sun, 20 Dec 2020 21:11:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5yp-0006SF-MG; Sun, 20 Dec 2020 21:11:03 +0000
Received: by outflank-mailman (input) for mailman id 57209;
 Sun, 20 Dec 2020 21:11:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yp-0006SA-0V
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yo-0006QG-VA
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yo-0000ad-TM
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=sh93tld7k5m4uxVuHvv9WbAp7id4Yzeez1d3klZgEEk=; b=jyMnTbHNMDszXs5TqGbJzxQVp3
	lUkB87T93xCYTnRawDvskGHboY1JSgeCij0dztY+9BTGYMgQoJaj2251SuFGW3xpLwT3XpNGl2+58
	2Wpy8NeyRBjBfpmOnm7RCYv4c/jhgh8QsQmNS85Ws/YyhCopy9V7yC4fMkuIXIwjLd8c=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: do permission checks on xenstore root
Message-Id: <E1kr5yo-0000ad-TM@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:02 +0000

commit 2fa586cb827737e08bf225521491bfd1aab18f22
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:18:08 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:08 2020 +0100

    tools/ocaml/xenstored: do permission checks on xenstore root
    
    This was lacking in a disappointing number of places.
    
    The xenstore root node is treated differently from all other nodes, because it
    doesn't have a parent, and mutation requires changing the parent.
    
    Unfortunately this lead to open-coding the special case for root into every
    single xenstore operation, and out of all the xenstore operations only read
    did a permission check when handling the root node.
    
    This means that an unprivileged guest can:
    
     * xenstore-chmod / to its liking and subsequently write new arbitrary nodes
       there (subject to quota)
     * xenstore-rm -r / deletes almost the entire xenstore tree (xenopsd quickly
       refills some, but you are left with a broken system)
     * DIRECTORY on / lists all children when called through python
       bindings (xenstore-ls stops at /local because it tries to list recursively)
     * get-perms on / works too, but that is just a minor information leak
    
    Add the missing permission checks, but this should really be refactored to do
    the root handling and permission checks on the node only once from a single
    function, instead of getting it wrong nearly everywhere.
    
    This is XSA-353.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index f299ec6461..92b6289b5e 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -273,15 +273,17 @@ let path_rm store perm path =
 			Node.del_childname node name
 		with Not_found ->
 			raise Define.Doesnt_exist in
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.del_all_children store.root
-	else
+	) else
 		Path.apply_modify store.root path do_rm
 
 let path_setperms store perm path perms =
-	if path = [] then
+	if path = [] then (
+		Node.check_perm store.root perm Perms.WRITE;
 		Node.set_perms store.root perms
-	else
+	) else
 		let do_setperms node name =
 			let c = Node.find node name in
 			Node.check_owner c perm;
@@ -313,9 +315,10 @@ let read store perm path =
 
 let ls store perm path =
 	let children =
-		if path = [] then
-			(Node.get_children store.root)
-		else
+		if path = [] then (
+			Node.check_perm store.root perm Perms.READ;
+			Node.get_children store.root
+		) else
 			let do_ls node name =
 				let cnode = Node.find node name in
 				Node.check_perm cnode perm Perms.READ;
@@ -324,9 +327,10 @@ let ls store perm path =
 	List.rev (List.map (fun n -> Symbol.to_string n.Node.name) children)
 
 let getperms store perm path =
-	if path = [] then
-		(Node.get_perms store.root)
-	else
+	if path = [] then (
+		Node.check_perm store.root perm Perms.READ;
+		Node.get_perms store.root
+	) else
 		let fct n name =
 			let c = Node.find n name in
 			Node.check_perm c perm Perms.READ;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57210.100020 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5yz-0006TH-R4; Sun, 20 Dec 2020 21:11:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57210.100020; Sun, 20 Dec 2020 21:11:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5yz-0006T9-Nz; Sun, 20 Dec 2020 21:11:13 +0000
Received: by outflank-mailman (input) for mailman id 57210;
 Sun, 20 Dec 2020 21:11:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yz-0006T3-3x
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yz-0006QJ-36
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5yz-0000bT-1I
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Nsejg8M2zw08xSoePYNyuz8pKHQY7lsUadA6BoC8Pzg=; b=U8DI0Bmd7LgNGwn9p4Aili1PIm
	eV2fekIUOVKf16jMvEajyJqbicyTjUP11l+MmFwT78Ki56kC81oO5Fr7GPRDw+bny5bC3x+m9TFmv
	xaKUn2ljYJBpzde0jAh6b1dTVBErhDclyE2ELJiSD9LF+JeCXxckO4NnB9FlUUZqRX34=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: allow removing child of a node exceeding quota
Message-Id: <E1kr5yz-0000bT-1I@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:13 +0000

commit 4959626e926ce2e6de731135b1f567433edcd992
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:37 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:22 2020 +0100

    tools/xenstore: allow removing child of a node exceeding quota
    
    An unprivileged user of Xenstore is not allowed to write nodes with a
    size exceeding a global quota, while privileged users like dom0 are
    allowed to write such nodes. The size of a node is the needed space
    to store all node specific data, this includes the names of all
    children of the node.
    
    When deleting a node its parent has to be modified by removing the
    name of the to be deleted child from it.
    
    This results in the strange situation that an unprivileged owner of a
    node might not succeed in deleting that node in case its parent is
    exceeding the quota of that unprivileged user (it might have been
    written by dom0), as the user is not allowed to write the updated
    parent node.
    
    Fix that by not checking the quota when writing a node for the
    purpose of removing a child's name only.
    
    The same applies to transaction handling: a node being read during a
    transaction is written to the transaction specific area and it should
    not be tested for exceeding the quota, as it might not be owned by
    the reader and presumably the original write would have failed if the
    node is owned by the reader.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 20 +++++++++++---------
 tools/xenstore/xenstored_core.h        |  3 ++-
 tools/xenstore/xenstored_transaction.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 97ceabf964..b43e1018ba 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	return node;
 }
 
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check)
 {
 	TDB_DATA data;
 	void *p;
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 		+ node->num_perms*sizeof(node->perms[0])
 		+ node->datalen + node->childlen;
 
-	if (domain_is_unprivileged(conn) &&
+	if (!no_quota_check && domain_is_unprivileged(conn) &&
 	    data.dsize >= quota_max_entry_size) {
 		errno = ENOSPC;
 		return errno;
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
 	return 0;
 }
 
-static int write_node(struct connection *conn, struct node *node)
+static int write_node(struct connection *conn, struct node *node,
+		      bool no_quota_check)
 {
 	TDB_DATA key;
 
 	if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
 		return errno;
 
-	return write_node_raw(conn, &key, node);
+	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	/* We write out the nodes down, setting destructor in case
 	 * something goes wrong. */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i)) {
+		if (write_node(conn, i, false)) {
 			domain_entry_dec(conn, i);
 			return NULL;
 		}
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 	} else {
 		node->data = in->buffer + offset;
 		node->datalen = datalen;
-		if (write_node(conn, node))
+		if (write_node(conn, node, false))
 			return errno;
 	}
 
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
 	size_t childlen = strlen(node->children + offset);
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node);
+	return write_node(conn, node, true);
 }
 
 
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
-	if (write_node(conn, node))
+	if (write_node(conn, node, false))
 		return errno;
 
 	fire_watches(conn, in, name, false);
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
 	if (child)
 		node->childlen = strlen(child) + 1;
 
-	if (write_node(NULL, node))
+	if (write_node(NULL, node, false))
 		barf_perror("Could not create initial node %s", name);
 	talloc_free(node);
 }
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index c4c32bc88f..29d638fbc5 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
 /* Write a node to the tdb data base. */
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
+		   bool no_quota_check);
 
 /* Get this node, checking we have permissions. */
 struct node *get_node(struct connection *conn,
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index 2824f7b359..e878975734 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
 			i->check_gen = true;
 			if (node->generation != NO_GENERATION) {
 				set_tdb_key(trans_name, &local_key);
-				ret = write_node_raw(conn, &local_key, node);
+				ret = write_node_raw(conn, &local_key, node, true);
 				if (ret)
 					goto err;
 				i->ta_node = true;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57211.100024 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5z9-0006Uo-Sk; Sun, 20 Dec 2020 21:11:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57211.100024; Sun, 20 Dec 2020 21:11:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5z9-0006Uh-Pk; Sun, 20 Dec 2020 21:11:23 +0000
Received: by outflank-mailman (input) for mailman id 57211;
 Sun, 20 Dec 2020 21:11:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5z9-0006UY-8g
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5z9-0006QX-6r
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5z9-0000cJ-5A
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=regxqMyaNTwUJkWUexm/yj7/MdnoRpv3jOyGbXXkrTA=; b=CIpRQYhQneINfdO2TyyklzsnTf
	8pKO8cpjV854i53qp2k1Bx7ummKGorcuA0cdeoCO1rfKgG42mvqRm+W+yQyXqY+Pf8TrtPeirk1xn
	RS2BWNlhJDUJ3qKkAHkqxXwbIrqEw75JLNTvhf6zLqPSFfEjRWApgY+9qKr6v/iCYVJo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: ignore transaction id for [un]watch
Message-Id: <E1kr5z9-0000cJ-5A@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:23 +0000

commit 2948458a63d4f65f17e348f68547a0bcffa1ee48
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:38 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:28 2020 +0100

    tools/xenstore: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b43e1018ba..bb2f9fd4e7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1268,13 +1268,17 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 static struct {
 	const char *str;
 	int (*func)(struct connection *conn, struct buffered_data *in);
+	unsigned int flags;
+#define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
 } const wire_funcs[XS_TYPE_COUNT] = {
 	[XS_CONTROL]           = { "CONTROL",           do_control },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
-	[XS_WATCH]             = { "WATCH",             do_watch },
-	[XS_UNWATCH]           = { "UNWATCH",           do_unwatch },
+	[XS_WATCH]             =
+	    { "WATCH",         do_watch,        XS_FLAG_NOTID },
+	[XS_UNWATCH]           =
+	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
 	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
@@ -1296,7 +1300,7 @@ static struct {
 
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].str)
+	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
 		return wire_funcs[type].str;
 
 	return "**UNKNOWN**";
@@ -1311,7 +1315,14 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	enum xsd_sockmsg_type type = in->hdr.msg.type;
 	int ret;
 
-	trans = transaction_lookup(conn, in->hdr.msg.tx_id);
+	if ((unsigned int)type >= XS_TYPE_COUNT || !wire_funcs[type].func) {
+		eprintf("Client unknown operation %i", type);
+		send_error(conn, ENOSYS);
+		return;
+	}
+
+	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
+		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
 		send_error(conn, -PTR_ERR(trans));
 		return;
@@ -1320,12 +1331,7 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 	assert(conn->transaction == NULL);
 	conn->transaction = trans;
 
-	if ((unsigned)type < XS_TYPE_COUNT && wire_funcs[type].func)
-		ret = wire_funcs[type].func(conn, in);
-	else {
-		eprintf("Client unknown operation %i", type);
-		ret = ENOSYS;
-	}
+	ret = wire_funcs[type].func(conn, in);
 	if (ret)
 		send_error(conn, ret);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57212.100028 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zJ-0006W5-UJ; Sun, 20 Dec 2020 21:11:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57212.100028; Sun, 20 Dec 2020 21:11:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zJ-0006Vy-RR; Sun, 20 Dec 2020 21:11:33 +0000
Received: by outflank-mailman (input) for mailman id 57212;
 Sun, 20 Dec 2020 21:11:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zJ-0006Vq-Ay
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zJ-0006Qf-9o
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zJ-0000d9-8v
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zFsnyxJKzIP8B84LDFtW3LTr9LkV+mz9z31t0I3pcwU=; b=xK6Pazrp4NcShZl8IdVx4eby7W
	a28ODyMfBMmhSxVeK9gHM54kPEbb662FrnKtYFMpolVKf4BLydq7xuiy72m+ROfcxehThLzGE6E5J
	BfV7kcsFkRqJp0eUmJq3uwa09fTCGgdC2KXAl2ZEHnyFyBXo/MwBoFVnqa/YrfE24GsM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: fix node accounting after failed node creation
Message-Id: <E1kr5zJ-0000d9-8v@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:33 +0000

commit 2007c635cbf39351623e2fd0dcfa526184aff1e8
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:39 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:33 2020 +0100

    tools/xenstore: fix node accounting after failed node creation
    
    When a node creation fails the number of nodes of the domain should be
    the same as before the failed node creation. In case of failure when
    trying to create a node requiring to create one or more intermediate
    nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't
    existing yet) it might happen that the number of nodes of the creating
    domain is not reset to the value it had before.
    
    So move the quota accounting out of construct_node() and into the node
    write loop in create_node() in order to be able to undo the accounting
    in case of an error in the intermediate node destructor.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index bb2f9fd4e7..db9b9ca795 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	if (!parent)
 		return NULL;
 
-	if (domain_entry(conn) >= quota_nb_entry_per_domain) {
-		errno = ENOSPC;
-		return NULL;
-	}
-
 	/* Add child to parent. */
 	base = basename(name);
 	baselen = strlen(base) + 1;
@@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 	node->children = node->data = NULL;
 	node->childlen = node->datalen = 0;
 	node->parent = parent;
-	domain_entry_inc(conn, node);
 	return node;
 
 nomem:
@@ -982,6 +976,9 @@ static int destroy_node(void *_node)
 	key.dsize = strlen(node->name);
 
 	tdb_delete(tdb_ctx, key);
+
+	domain_entry_dec(talloc_parent(node), node);
+
 	return 0;
 }
 
@@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx,
 	node->data = data;
 	node->datalen = datalen;
 
-	/* We write out the nodes down, setting destructor in case
-	 * something goes wrong. */
+	/*
+	 * We write out the nodes bottom up.
+	 * All new created nodes will have i->parent set, while the final
+	 * node will be already existing and won't have i->parent set.
+	 * New nodes are subject to quota handling.
+	 * Initially set a destructor for all new nodes removing them from
+	 * TDB again and undoing quota accounting for the case of an error
+	 * during the write loop.
+	 */
 	for (i = node; i; i = i->parent) {
-		if (write_node(conn, i, false)) {
-			domain_entry_dec(conn, i);
+		/* i->parent is set for each new node, so check quota. */
+		if (i->parent &&
+		    domain_entry(conn) >= quota_nb_entry_per_domain) {
+			errno = ENOSPC;
 			return NULL;
 		}
-		talloc_set_destructor(i, destroy_node);
+		if (write_node(conn, i, false))
+			return NULL;
+
+		/* Account for new node, set destructor for error case. */
+		if (i->parent) {
+			domain_entry_inc(conn, i);
+			talloc_set_destructor(i, destroy_node);
+		}
 	}
 
 	/* OK, now remove destructors so they stay around */
-	for (i = node; i; i = i->parent)
+	for (i = node; i->parent; i = i->parent)
 		talloc_set_destructor(i, NULL);
 	return node;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57213.100031 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zU-0006XR-W8; Sun, 20 Dec 2020 21:11:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57213.100031; Sun, 20 Dec 2020 21:11:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zU-0006XI-TA; Sun, 20 Dec 2020 21:11:44 +0000
Received: by outflank-mailman (input) for mailman id 57213;
 Sun, 20 Dec 2020 21:11:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zT-0006X9-EJ
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zT-0006Qn-DT
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zT-0000dr-Bm
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AQ4o2GQ0v/pRvdUJP/Ke/2EOgsHo9mUBZWr9p699FwQ=; b=wjDLZRbPEiw3YTm+LWyMPIPY4s
	Ci/LcnCIX3vkBem5tDs9vwDYLcCxPBTO4AGPZaSIwD8jBXDhyKVsqBVfU328RVek7m81SOXDSqKu3
	gr1sxlIuSXnVv3W7XFfPmU5LVOeecQuSkuUhHetYpuU5iPzLQlDTOtE42Yuj0RirjucY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: simplify and rename check_event_node()
Message-Id: <E1kr5zT-0000dr-Bm@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:43 +0000

commit 1ab192f4eac9c264588723fa49137279bcafe780
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:40 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:39 2020 +0100

    tools/xenstore: simplify and rename check_event_node()
    
    There is no path which allows to call check_event_node() without a
    event name. So don't let the result depend on the name being NULL and
    add an assert() covering that case.
    
    Rename the function to check_special_event() to better match the
    semantics.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_watch.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 7dedca60df..f2f1bed47c 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -47,13 +47,11 @@ struct watch
 	char *node;
 };
 
-static bool check_event_node(const char *node)
+static bool check_special_event(const char *name)
 {
-	if (!node || !strstarts(node, "@")) {
-		errno = EINVAL;
-		return false;
-	}
-	return true;
+	assert(name);
+
+	return strstarts(name, "@");
 }
 
 /* Is child a subnode of parent, or equal? */
@@ -87,7 +85,7 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_event_node(name)) {
+	if (!check_special_event(name)) {
 		/* Can this conn load node, or see that it doesn't exist? */
 		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
 		/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:11:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:11:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57214.100035 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zf-0006Zi-2A; Sun, 20 Dec 2020 21:11:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57214.100035; Sun, 20 Dec 2020 21:11:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5ze-0006ZZ-Uf; Sun, 20 Dec 2020 21:11:54 +0000
Received: by outflank-mailman (input) for mailman id 57214;
 Sun, 20 Dec 2020 21:11:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zd-0006Yc-J6
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zd-0006RB-HQ
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zd-0000ej-Fc
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:11:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8++5U78fKg6JAmZMPlW4JJXHKBmoAjM4KY3lz6vZASU=; b=3ADI44Yrmtpb7p+Mr6OVWfM2DZ
	jjSz3F9uYdO2shiC/0ds0dobbxIB0Fxm+q0aQdiZlE9wzxahYBfy8Sek6dMKCIDVW2IVvZLajbKrw
	E8vamJ+KP6HdywRP8AAXl5fBUqke2vFKzS+kFW8Ra6/dSZ0CPBCi03U5MORmd/K2lYDk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kr5zd-0000ej-Fc@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:11:53 +0000

commit 1819c9dbe8f93e832a18db61390948e35f5862c5
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:44 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index db9b9ca795..6afd584311 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
 	int (*func)(struct connection *conn, struct buffered_data *in);
 	unsigned int flags;
 #define XS_FLAG_NOTID		(1U << 0)	/* Ignore transaction id. */
+#define XS_FLAG_PRIV		(1U << 1)	/* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-	[XS_CONTROL]           = { "CONTROL",           do_control },
+	[XS_CONTROL]           =
+	    { "CONTROL",       do_control,      XS_FLAG_PRIV },
 	[XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
 	[XS_READ]              = { "READ",              do_read },
 	[XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
 	    { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
 	[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
 	[XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-	[XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-	[XS_RELEASE]           = { "RELEASE",           do_release },
+	[XS_INTRODUCE]         =
+	    { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+	[XS_RELEASE]           =
+	    { "RELEASE",       do_release,      XS_FLAG_PRIV },
 	[XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
 	[XS_WRITE]             = { "WRITE",             do_write },
 	[XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
 	[XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
 	[XS_ERROR]             = { "ERROR",             NULL },
 	[XS_IS_DOMAIN_INTRODUCED] =
-			{ "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-	[XS_RESUME]            = { "RESUME",            do_resume },
-	[XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+	    { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+	[XS_RESUME]            =
+	    { "RESUME",        do_resume,       XS_FLAG_PRIV },
+	[XS_SET_TARGET]        =
+	    { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
 	[XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, struct buffered_data *in)
 		return;
 	}
 
+	if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+	    domain_is_unprivileged(conn)) {
+		send_error(conn, EACCES);
+		return;
+	}
+
 	trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
 		? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
 	if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 1eae703ef6..0e2926e2a3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -377,7 +377,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -445,7 +445,7 @@ int do_set_target(struct connection *conn, struct buffered_data *in)
 	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
 		return EINVAL;
 
-	if (domain_is_unprivileged(conn) || !conn->can_write)
+	if (!conn->can_write)
 		return EACCES;
 
 	domid = atoi(vec[0]);
@@ -480,9 +480,6 @@ static struct domain *onearg_domain(struct connection *conn,
 	if (!domid)
 		return ERR_PTR(-EINVAL);
 
-	if (domain_is_unprivileged(conn))
-		return ERR_PTR(-EACCES);
-
 	return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57215.100040 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zp-0006bs-4Q; Sun, 20 Dec 2020 21:12:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57215.100040; Sun, 20 Dec 2020 21:12:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zp-0006bk-1I; Sun, 20 Dec 2020 21:12:05 +0000
Received: by outflank-mailman (input) for mailman id 57215;
 Sun, 20 Dec 2020 21:12:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zn-0006bX-LK
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zn-0006RZ-KY
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zn-0000fZ-Ja
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=0dJnhAtMbY+ydmMnDZs1lfh3jd//zCpBQk0aBLMFcV4=; b=C1y8Idmb2kcuj25Yv0tSmDI6Pw
	mIZEtRAbTcEcJxrbz36wckwn3ey0lRigmVoFpT7wBnL5/OSUZnQ6ulXjFhMNaky5Qp54nHR7KY2Le
	qtLqLxOisgjj4zYYmOkd2s3H1W95YhtOu/O9koFvmWbc9Iqj5LElTYRS0WDfVWLdbaR0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: rework node removal
Message-Id: <E1kr5zn-0000fZ-Ja@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:03 +0000

commit ee416da072f43268a1065bda6a80d09daf9efc1c
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:42 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:49 2020 +0100

    tools/xenstore: rework node removal
    
    Today a Xenstore node is being removed by deleting it from the parent
    first and then deleting itself and all its children. This results in
    stale entries remaining in the data base in case e.g. a memory
    allocation is failing during processing. This would result in the
    rather strange behavior to be able to read a node (as its still in the
    data base) while not being visible in the tree view of Xenstore.
    
    Fix that by deleting the nodes from the leaf side instead of starting
    at the root.
    
    As fire_watches() is now called from _rm() the ctx parameter needs a
    const attribute.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 99 +++++++++++++++++++++-------------------
 tools/xenstore/xenstored_watch.c |  4 +-
 tools/xenstore/xenstored_watch.h |  2 +-
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 6afd584311..1cb729a2cd 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1087,74 +1087,76 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 	return 0;
 }
 
-static void delete_node(struct connection *conn, struct node *node)
-{
-	unsigned int i;
-	char *name;
-
-	/* Delete self, then delete children.  If we crash, then the worst
-	   that can happen is the children will continue to take up space, but
-	   will otherwise be unreachable. */
-	delete_node_single(conn, node);
-
-	/* Delete children, too. */
-	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
-		struct node *child;
-
-		name = talloc_asprintf(node, "%s/%s", node->name,
-				       node->children + i);
-		child = name ? read_node(conn, node, name) : NULL;
-		if (child) {
-			delete_node(conn, child);
-		}
-		else {
-			trace("delete_node: Error deleting child '%s/%s'!\n",
-			      node->name, node->children + i);
-			/* Skip it, we've already deleted the parent. */
-		}
-		talloc_free(name);
-	}
-}
-
-
 /* Delete memory using memmove. */
 static void memdel(void *mem, unsigned off, unsigned len, unsigned total)
 {
 	memmove(mem + off, mem + off + len, total - off - len);
 }
 
-
-static int remove_child_entry(struct connection *conn, struct node *node,
-			      size_t offset)
+static void remove_child_entry(struct connection *conn, struct node *node,
+			       size_t offset)
 {
 	size_t childlen = strlen(node->children + offset);
+
 	memdel(node->children, offset, childlen + 1, node->childlen);
 	node->childlen -= childlen + 1;
-	return write_node(conn, node, true);
+	if (write_node(conn, node, true))
+		corrupt(conn, "Can't update parent node '%s'", node->name);
 }
 
-
-static int delete_child(struct connection *conn,
-			struct node *node, const char *childname)
+static void delete_child(struct connection *conn,
+			 struct node *node, const char *childname)
 {
 	unsigned int i;
 
 	for (i = 0; i < node->childlen; i += strlen(node->children+i) + 1) {
 		if (streq(node->children+i, childname)) {
-			return remove_child_entry(conn, node, i);
+			remove_child_entry(conn, node, i);
+			return;
 		}
 	}
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
-	return ENOENT;
 }
 
+static int delete_node(struct connection *conn, struct node *parent,
+		       struct node *node)
+{
+	char *name;
+
+	/* Delete children. */
+	while (node->childlen) {
+		struct node *child;
+
+		name = talloc_asprintf(node, "%s/%s", node->name,
+				       node->children);
+		child = name ? read_node(conn, node, name) : NULL;
+		if (child) {
+			if (delete_node(conn, node, child))
+				return errno;
+		} else {
+			trace("delete_node: Error deleting child '%s/%s'!\n",
+			      node->name, node->children);
+			/* Quit deleting. */
+			errno = ENOMEM;
+			return errno;
+		}
+		talloc_free(name);
+	}
+
+	delete_node_single(conn, node);
+	delete_child(conn, parent, basename(node->name));
+	talloc_free(node);
+
+	return 0;
+}
 
 static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	       const char *name)
 {
-	/* Delete from parent first, then if we crash, the worst that can
-	   happen is the child will continue to take up space, but will
-	   otherwise be unreachable. */
+	/*
+	 * Deleting node by node, so the result is always consistent even in
+	 * case of a failure.
+	 */
 	struct node *parent;
 	char *parentname = get_parent(ctx, name);
 
@@ -1165,11 +1167,13 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
 
-	if (delete_child(conn, parent, basename(name)))
-		return EINVAL;
-
-	delete_node(conn, node);
-	return 0;
+	/*
+	 * Fire the watches now, when we can still see the node permissions.
+	 * This fine as we are single threaded and the next possible read will
+	 * be handled only after the node has been really removed.
+	 */
+	fire_watches(conn, ctx, name, true);
+	return delete_node(conn, parent, node);
 }
 
 
@@ -1207,7 +1211,6 @@ static int do_rm(struct connection *conn, struct buffered_data *in)
 	if (ret)
 		return ret;
 
-	fire_watches(conn, in, name, true);
 	send_ack(conn, XS_RM);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f2f1bed47c..f0bbfe7a6d 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -77,7 +77,7 @@ static bool is_child(const char *child, const char *parent)
  * Temporary memory allocations are done with ctx.
  */
 static void add_event(struct connection *conn,
-		      void *ctx,
+		      const void *ctx,
 		      struct watch *watch,
 		      const char *name)
 {
@@ -121,7 +121,7 @@ static void add_event(struct connection *conn,
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
  */
-void fire_watches(struct connection *conn, void *ctx, const char *name,
+void fire_watches(struct connection *conn, const void *ctx, const char *name,
 		  bool recurse)
 {
 	struct connection *i;
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index c72ea6a685..54d4ea7e0d 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -25,7 +25,7 @@ int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: recurse means all the children are affected (ie. rm). */
-void fire_watches(struct connection *conn, void *tmp, const char *name,
+void fire_watches(struct connection *conn, const void *tmp, const char *name,
 		  bool recurse);
 
 void conn_delete_all_watches(struct connection *conn);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57216.100044 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zz-0006di-69; Sun, 20 Dec 2020 21:12:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57216.100044; Sun, 20 Dec 2020 21:12:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr5zz-0006dZ-2t; Sun, 20 Dec 2020 21:12:15 +0000
Received: by outflank-mailman (input) for mailman id 57216;
 Sun, 20 Dec 2020 21:12:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zx-0006dO-Qu
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zx-0006Ri-O4
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:13 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr5zx-0000gH-Mi
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:13 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=EvVM+pe+zfGtPvMGXA2DAQVvvNOdO/Ov/ZyNf1lB8Lo=; b=L1x/578dOw7XIheisBHJKaVQCb
	4+nQ0fmeAOwefjicErWOaIp33y4QCyqJ8XFxGQOSG5uXr7klFg43ALzW+vS/a8z01ZvPDaljO/9dh
	rPgRivBjN8yXNLA8VnuSGpMAPVWSLy0sTvCXnDeFYn5FheXmyjm5ROpe7Vt9MmiKKE4A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: fire watches only when removing a specific node
Message-Id: <E1kr5zx-0000gH-Mi@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:13 +0000

commit b8f23da652610d3cc8a2d76740aa8d1f5d7d05ba
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:43 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:54 2020 +0100

    tools/xenstore: fire watches only when removing a specific node
    
    Instead of firing all watches for removing a subtree in one go, do so
    only when the related node is being removed.
    
    The watches for the top-most node being removed include all watches
    including that node, while watches for nodes below that are only fired
    if they are matching exactly. This avoids firing any watch more than
    once when removing a subtree.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c  | 11 ++++++-----
 tools/xenstore/xenstored_watch.c | 13 ++++++++-----
 tools/xenstore/xenstored_watch.h |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1cb729a2cd..d7c025616e 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1118,8 +1118,8 @@ static void delete_child(struct connection *conn,
 	corrupt(conn, "Can't find child '%s' in %s", childname, node->name);
 }
 
-static int delete_node(struct connection *conn, struct node *parent,
-		       struct node *node)
+static int delete_node(struct connection *conn, const void *ctx,
+		       struct node *parent, struct node *node)
 {
 	char *name;
 
@@ -1131,7 +1131,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 				       node->children);
 		child = name ? read_node(conn, node, name) : NULL;
 		if (child) {
-			if (delete_node(conn, node, child))
+			if (delete_node(conn, ctx, node, child))
 				return errno;
 		} else {
 			trace("delete_node: Error deleting child '%s/%s'!\n",
@@ -1143,6 +1143,7 @@ static int delete_node(struct connection *conn, struct node *parent,
 		talloc_free(name);
 	}
 
+	fire_watches(conn, ctx, node->name, true);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1172,8 +1173,8 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, true);
-	return delete_node(conn, parent, node);
+	fire_watches(conn, ctx, name, false);
+	return delete_node(conn, ctx, parent, node);
 }
 
 
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f0bbfe7a6d..3836675459 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -122,7 +122,7 @@ static void add_event(struct connection *conn,
  * Temporary memory allocations are done with ctx.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool recurse)
+		  bool exact)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,10 +134,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		list_for_each_entry(watch, &i->watches, list) {
-			if (is_child(name, watch->node))
-				add_event(i, ctx, watch, name);
-			else if (recurse && is_child(watch->node, name))
-				add_event(i, ctx, watch, watch->node);
+			if (exact) {
+				if (streq(name, watch->node))
+					add_event(i, ctx, watch, name);
+			} else {
+				if (is_child(name, watch->node))
+					add_event(i, ctx, watch, name);
+			}
 		}
 	}
 }
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 54d4ea7e0d..1b3c80d3dd 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -24,9 +24,9 @@
 int do_watch(struct connection *conn, struct buffered_data *in);
 int do_unwatch(struct connection *conn, struct buffered_data *in);
 
-/* Fire all watches: recurse means all the children are affected (ie. rm). */
+/* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool recurse);
+		  bool exact);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57217.100047 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr609-0006ev-7o; Sun, 20 Dec 2020 21:12:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57217.100047; Sun, 20 Dec 2020 21:12:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr609-0006en-4U; Sun, 20 Dec 2020 21:12:25 +0000
Received: by outflank-mailman (input) for mailman id 57217;
 Sun, 20 Dec 2020 21:12:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr607-0006ef-Rm
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr607-0006Rp-Qz
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr607-0000hB-QH
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=1u1squoTsirTm6ob/7WcmBhKVet0vOHpKYfg0S0FeDQ=; b=pmLcJu8/nuJgOtpPG7NiBtzhQd
	juY+bSBj+lW3SozXmVz+lAvn/rOquyF00d08vXTC8/Z7dESiCBGjWMQ9ckV6eqsT9MHwtCTNgzrzh
	5x13Q41KfBWNTUjR4pYYn3wQm7/EvIKtdoMNi7bEhtTyz8As+ibxeqz8s3kah3owB12I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: introduce node_perms structure
Message-Id: <E1kr607-0000hB-QH@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:23 +0000

commit ef765f6ebc3d67c02814f654c876fbd010f97792
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:44 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:18:59 2020 +0100

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index d7c025616e..fe9943113b 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, const void *ctx,
 	/* Datalen, childlen, number of permissions */
 	hdr = (void *)data.dptr;
 	node->generation = hdr->generation;
-	node->num_perms = hdr->num_perms;
+	node->perms.num = hdr->num_perms;
 	node->datalen = hdr->datalen;
 	node->childlen = hdr->childlen;
 
 	/* Permissions are struct xs_permissions. */
-	node->perms = hdr->perms;
+	node->perms.p = hdr->perms;
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms + node->num_perms;
+	node->data = node->perms.p + node->perms.num;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	struct xs_tdb_record_hdr *hdr;
 
 	data.dsize = sizeof(*hdr)
-		+ node->num_perms*sizeof(node->perms[0])
+		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
 
 	if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	data.dptr = talloc_size(node, data.dsize);
 	hdr = (void *)data.dptr;
 	hdr->generation = node->generation;
-	hdr->num_perms = node->num_perms;
+	hdr->num_perms = node->perms.num;
 	hdr->datalen = node->datalen;
 	hdr->childlen = node->childlen;
 
-	memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-	p = hdr->perms + node->num_perms;
+	memcpy(hdr->perms, node->perms.p,
+	       node->perms.num * sizeof(*node->perms.p));
+	p = hdr->perms + node->perms.num;
 	memcpy(p, node->data, node->datalen);
 	p += node->datalen;
 	memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node *node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       struct xs_permissions *perms,
-				       unsigned int num)
+				       const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection *conn,
 		mask &= ~XS_PERM_WRITE;
 
 	/* Owners and tools get it all... */
-	if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+	if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-	for (i = 1; i < num; i++)
-		if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-			return perms[i].perms & mask;
+	for (i = 1; i < perms->num; i++)
+		if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == conn->target->id))
+			return perms->p[i].perms & mask;
 
-	return perms[0].perms & mask;
+	return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void *ctx,
 		return 0;
 	}
 
-	*perm = perm_for_conn(conn, node->perms, node->num_perms);
+	*perm = perm_for_conn(conn, &node->perms);
 	return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
 	node = read_node(conn, ctx, name);
 	/* If we don't have permission, we don't have node. */
 	if (node) {
-		if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-		    != perm) {
+		if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
 			errno = EACCES;
 			node = NULL;
 		}
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
 	return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-			      struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
 			      unsigned int *len)
 {
 	unsigned int i;
 	char *strings = NULL;
 	char buffer[MAX_STRLEN(unsigned int) + 1];
 
-	for (*len = 0, i = 0; i < num; i++) {
-		if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+	for (*len = 0, i = 0; i < perms->num; i++) {
+		if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
 			return NULL;
 
 		strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection *conn, const void *ctx,
 		goto nomem;
 
 	/* Inherit permissions, except unprivileged domains own what they create */
-	node->num_perms = parent->num_perms;
-	node->perms = talloc_memdup(node, parent->perms,
-				    node->num_perms * sizeof(node->perms[0]));
-	if (!node->perms)
+	node->perms.num = parent->perms.num;
+	node->perms.p = talloc_memdup(node, parent->perms.p,
+				      node->perms.num * sizeof(*node->perms.p));
+	if (!node->perms.p)
 		goto nomem;
 	if (domain_is_unprivileged(conn))
-		node->perms[0].id = conn->id;
+		node->perms.p[0].id = conn->id;
 
 	/* No children, no data */
 	node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 	if (!node)
 		return errno;
 
-	strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+	strings = perms_to_strings(node, &node->perms, &len);
 	if (!strings)
 		return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	unsigned int num;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 	char *name, *permstr;
 	struct node *node;
 
-	num = xs_count_strings(in->buffer, in->used);
-	if (num < 2)
+	perms.num = xs_count_strings(in->buffer, in->used);
+	if (perms.num < 2)
 		return EINVAL;
 
 	/* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 		return errno;
 
 	permstr = in->buffer + strlen(in->buffer) + 1;
-	num--;
+	perms.num--;
 
-	perms = talloc_array(node, struct xs_permissions, num);
-	if (!perms)
+	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	if (!perms.p)
 		return ENOMEM;
-	if (!xs_strings_to_perms(perms, num, permstr))
+	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
 	/* Unprivileged domains may not change the owner. */
-	if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+	if (domain_is_unprivileged(conn) &&
+	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
 	domain_entry_dec(conn, node);
 	node->perms = perms;
-	node->num_perms = num;
 	domain_entry_inc(conn, node);
 
 	if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char *child)
 		barf_perror("Could not allocate initial node %s", name);
 
 	node->name = name;
-	node->perms = &perms;
-	node->num_perms = 1;
+	node->perms.p = &perms;
+	node->perms.num = 1;
 	node->children = (char *)child;
 	if (child)
 		node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 29d638fbc5..47ba0916db 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -109,6 +109,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+	unsigned int num;
+	struct xs_permissions *p;
+};
+
 struct node {
 	const char *name;
 
@@ -120,8 +125,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
 	/* Permissions. */
-	unsigned int num_perms;
-	struct xs_permissions *perms;
+	struct node_perms perms;
 
 	/* Contents. */
 	unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0e2926e2a3..dc51cdfa9a 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -657,12 +657,12 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_inc(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d)
 				d->nbentry++;
 		}
@@ -683,12 +683,12 @@ void domain_entry_dec(struct connection *conn, struct node *node)
 	if (!conn)
 		return;
 
-	if (node->perms && node->perms[0].id != conn->id) {
+	if (node->perms.p && node->perms.p[0].id != conn->id) {
 		if (conn->transaction) {
 			transaction_entry_dec(conn->transaction,
-				node->perms[0].id);
+				node->perms.p[0].id);
 		} else {
-			d = find_domain_by_domid(node->perms[0].id);
+			d = find_domain_by_domid(node->perms.p[0].id);
 			if (d && d->nbentry)
 				d->nbentry--;
 		}
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57218.100051 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60J-0006gE-95; Sun, 20 Dec 2020 21:12:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57218.100051; Sun, 20 Dec 2020 21:12:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60J-0006g6-66; Sun, 20 Dec 2020 21:12:35 +0000
Received: by outflank-mailman (input) for mailman id 57218;
 Sun, 20 Dec 2020 21:12:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60H-0006fw-VD
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60H-0006Rx-U3
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60H-0000hv-TH
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=zXVevz4SiVfKf8Sz/WEsPbgGjP3xAGiLEGAlWKYBBy8=; b=vdy553S6JArwx3SqLyiDFpJkLR
	rHnOUAIXWIPiD2lB6hlSQKIjpunSiEk312cvgCTKHf8P/+jLjrhb0u3gpDA0KMuWZNO4GpN0xa4TW
	ic6QlwCYB0+AtAV0jBZK4yH9BvZLMJfuFzxhKylspgrHc6jyDLj155No2H8xqs+FTUw0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: allow special watches for privileged callers only
Message-Id: <E1kr60H-0000hv-TH@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:33 +0000

commit 8cc0a86379f9b1544ab274bae69423c603d01b93
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:45 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:04 2020 +0100

    tools/xenstore: allow special watches for privileged callers only
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    In order to allow for disaggregated setups where e.g. driver domains
    need to make use of those special watches add support for calling
    "set permissions" for those special nodes, too.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 docs/misc/xenstore.txt            |  5 ++++
 tools/xenstore/xenstored_core.c   | 27 +++++++++++-------
 tools/xenstore/xenstored_core.h   |  2 ++
 tools/xenstore/xenstored_domain.c | 60 +++++++++++++++++++++++++++++++++++++++
 tools/xenstore/xenstored_domain.h |  5 ++++
 tools/xenstore/xenstored_watch.c  |  4 +++
 6 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt
index 6f8569d576..32969eb3fe 100644
--- a/docs/misc/xenstore.txt
+++ b/docs/misc/xenstore.txt
@@ -170,6 +170,9 @@ SET_PERMS		<path>|<perm-as-string>|+?
 		n<domid>	no access
 	See http://wiki.xen.org/wiki/XenBus section
 	`Permissions' for details of the permissions system.
+	It is possible to set permissions for the special watch paths
+	"@introduceDomain" and "@releaseDomain" to enable receiving those
+	watches in unprivileged domains.
 
 ---------- Watches ----------
 
@@ -194,6 +197,8 @@ WATCH			<wpath>|<token>|?
 	    @releaseDomain 	occurs on any domain crash or
 				shutdown, and also on RELEASE
 				and domain destruction
+	<wspecial> events are sent to privileged callers or explicitly
+	via SET_PERMS enabled domains only.
 
 	When a watch is first set up it is triggered once straight
 	away, with <path> equal to <wpath>.  Watches may be triggered
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fe9943113b..720bec269d 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -468,8 +468,8 @@ static int write_node(struct connection *conn, struct node *node,
 	return write_node_raw(conn, &key, node, no_quota_check);
 }
 
-static enum xs_perm_type perm_for_conn(struct connection *conn,
-				       const struct node_perms *perms)
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms)
 {
 	unsigned int i;
 	enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -1245,22 +1245,29 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	/* First arg is node name. */
-	/* We must own node to do this (tools can do this too). */
-	node = get_node_canonicalized(conn, in, in->buffer, &name,
-				      XS_PERM_WRITE | XS_PERM_OWNER);
-	if (!node)
-		return errno;
-
 	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
 
-	perms.p = talloc_array(node, struct xs_permissions, perms.num);
+	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
 		return ENOMEM;
 	if (!xs_strings_to_perms(perms.p, perms.num, permstr))
 		return errno;
 
+	/* First arg is node name. */
+	if (strstarts(in->buffer, "@")) {
+		if (set_perms_special(conn, in->buffer, &perms))
+			return errno;
+		send_ack(conn, XS_SET_PERMS);
+		return 0;
+	}
+
+	/* We must own node to do this (tools can do this too). */
+	node = get_node_canonicalized(conn, in, in->buffer, &name,
+				      XS_PERM_WRITE | XS_PERM_OWNER);
+	if (!node)
+		return errno;
+
 	/* Unprivileged domains may not change the owner. */
 	if (domain_is_unprivileged(conn) &&
 	    perms.p[0].id != node->perms.p[0].id)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 47ba0916db..53f1050859 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -165,6 +165,8 @@ struct node *get_node(struct connection *conn,
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
 void corrupt(struct connection *conn, const char *fmt, ...);
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
 
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index dc51cdfa9a..7afabe0ae0 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -41,6 +41,9 @@ static evtchn_port_t virq_port;
 
 xenevtchn_handle *xce_handle = NULL;
 
+static struct node_perms dom_release_perms;
+static struct node_perms dom_introduce_perms;
+
 struct domain
 {
 	struct list_head list;
@@ -589,6 +592,59 @@ void restore_existing_connections(void)
 {
 }
 
+static int set_dom_perms_default(struct node_perms *perms)
+{
+	perms->num = 1;
+	perms->p = talloc_array(NULL, struct xs_permissions, perms->num);
+	if (!perms->p)
+		return -1;
+	perms->p->id = 0;
+	perms->p->perms = XS_PERM_NONE;
+
+	return 0;
+}
+
+static struct node_perms *get_perms_special(const char *name)
+{
+	if (!strcmp(name, "@releaseDomain"))
+		return &dom_release_perms;
+	if (!strcmp(name, "@introduceDomain"))
+		return &dom_introduce_perms;
+	return NULL;
+}
+
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return EINVAL;
+
+	if ((perm_for_conn(conn, p) & (XS_PERM_WRITE | XS_PERM_OWNER)) !=
+	    (XS_PERM_WRITE | XS_PERM_OWNER))
+		return EACCES;
+
+	p->num = perms->num;
+	talloc_free(p->p);
+	p->p = perms->p;
+	talloc_steal(NULL, perms->p);
+
+	return 0;
+}
+
+bool check_perms_special(const char *name, struct connection *conn)
+{
+	struct node_perms *p;
+
+	p = get_perms_special(name);
+	if (!p)
+		return false;
+
+	return perm_for_conn(conn, p) & XS_PERM_READ;
+}
+
 static int dom0_init(void) 
 { 
 	evtchn_port_t port;
@@ -610,6 +666,10 @@ static int dom0_init(void)
 
 	xenevtchn_notify(xce_handle, dom0->port);
 
+	if (set_dom_perms_default(&dom_release_perms) ||
+	    set_dom_perms_default(&dom_introduce_perms))
+		return -1;
+
 	return 0; 
 }
 
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 56ae015974..259183962a 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -65,6 +65,11 @@ void domain_watch_inc(struct connection *conn);
 void domain_watch_dec(struct connection *conn);
 int domain_watch(struct connection *conn);
 
+/* Special node permission handling. */
+int set_perms_special(struct connection *conn, const char *name,
+		      struct node_perms *perms);
+bool check_perms_special(const char *name, struct connection *conn);
+
 /* Write rate limiting */
 
 #define WRL_FACTOR   1000 /* for fixed-point arithmetic */
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 3836675459..f4e289362e 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -133,6 +133,10 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
+		/* introduce/release domain watches */
+		if (check_special_event(name) && !check_perms_special(name, i))
+			continue;
+
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
 				if (streq(name, watch->node))
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57219.100057 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60T-0006hf-Dp; Sun, 20 Dec 2020 21:12:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57219.100057; Sun, 20 Dec 2020 21:12:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60T-0006hX-A5; Sun, 20 Dec 2020 21:12:45 +0000
Received: by outflank-mailman (input) for mailman id 57219;
 Sun, 20 Dec 2020 21:12:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60S-0006hP-1e
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60S-0006S6-0p
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60S-0000ij-06
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=/xno/Wkfc7ouC07e3TqMwT1TCEvmtO5H5TMmTxOCAzI=; b=jUzSKnKMexvmpzZeD9gCLndood
	IoownA4boFTKG6mmlJ0cOae+z1MtIlyIRI+jM/H2v4aWPNQdTGzFw2hzZyWiX7mx7scHhjY7aLLP3
	hgyIGyA2kIPxYu69eue6ydlIyxnQ5DfuLqnsQlegg8cSpvN6gfPTD51uAvTJUUvL+Tnw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: avoid watch events for nodes without access
Message-Id: <E1kr60S-0000ij-06@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:44 +0000

commit 60e3727bcae7268a57aa240c799b1bc788c9c39b
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Thu Jun 11 16:12:46 2020 +0200
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:09 2020 +0100

    tools/xenstore: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    [julieng: Handle rebase conflict]
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c        | 28 +++++++------
 tools/xenstore/xenstored_core.h        | 15 ++++---
 tools/xenstore/xenstored_domain.c      |  6 +--
 tools/xenstore/xenstored_transaction.c | 21 +++++++++-
 tools/xenstore/xenstored_watch.c       | 75 +++++++++++++++++++++++++---------
 tools/xenstore/xenstored_watch.h       |  2 +-
 6 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 720bec269d..1c28454545 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -358,8 +358,8 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations will be done with ctx.
  */
-static struct node *read_node(struct connection *conn, const void *ctx,
-			      const char *name)
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name)
 {
 	TDB_DATA key, data;
 	struct xs_tdb_record_hdr *hdr;
@@ -494,7 +494,7 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
  * Get name of node parent.
  * Temporary memory allocations are done with ctx.
  */
-static char *get_parent(const void *ctx, const char *node)
+char *get_parent(const void *ctx, const char *node)
 {
 	char *parent;
 	char *slash = strrchr(node + 1, '/');
@@ -566,10 +566,10 @@ static int errno_from_parents(struct connection *conn, const void *ctx,
  * If it fails, returns NULL and sets errno.
  * Temporary memory allocations are done with ctx.
  */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm)
+static struct node *get_node(struct connection *conn,
+			     const void *ctx,
+			     const char *name,
+			     enum xs_perm_type perm)
 {
 	struct node *node;
 
@@ -1056,7 +1056,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
 			return errno;
 	}
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, NULL);
 	send_ack(conn, XS_WRITE);
 
 	return 0;
@@ -1078,7 +1078,7 @@ static int do_mkdir(struct connection *conn, struct buffered_data *in)
 		node = create_node(conn, in, name, NULL, 0);
 		if (!node)
 			return errno;
-		fire_watches(conn, in, name, false);
+		fire_watches(conn, in, name, node, false, NULL);
 	}
 	send_ack(conn, XS_MKDIR);
 
@@ -1141,7 +1141,7 @@ static int delete_node(struct connection *conn, const void *ctx,
 		talloc_free(name);
 	}
 
-	fire_watches(conn, ctx, node->name, true);
+	fire_watches(conn, ctx, node->name, node, true, NULL);
 	delete_node_single(conn, node);
 	delete_child(conn, parent, basename(node->name));
 	talloc_free(node);
@@ -1165,13 +1165,14 @@ static int _rm(struct connection *conn, const void *ctx, struct node *node,
 	parent = read_node(conn, ctx, parentname);
 	if (!parent)
 		return (errno == ENOMEM) ? ENOMEM : EINVAL;
+	node->parent = parent;
 
 	/*
 	 * Fire the watches now, when we can still see the node permissions.
 	 * This fine as we are single threaded and the next possible read will
 	 * be handled only after the node has been really removed.
 	 */
-	fire_watches(conn, ctx, name, false);
+	fire_watches(conn, ctx, name, node, false, NULL);
 	return delete_node(conn, ctx, parent, node);
 }
 
@@ -1237,7 +1238,7 @@ static int do_get_perms(struct connection *conn, struct buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-	struct node_perms perms;
+	struct node_perms perms, old_perms;
 	char *name, *permstr;
 	struct node *node;
 
@@ -1273,6 +1274,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	    perms.p[0].id != node->perms.p[0].id)
 		return EPERM;
 
+	old_perms = node->perms;
 	domain_entry_dec(conn, node);
 	node->perms = perms;
 	domain_entry_inc(conn, node);
@@ -1280,7 +1282,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (write_node(conn, node, false))
 		return errno;
 
-	fire_watches(conn, in, name, false);
+	fire_watches(conn, in, name, node, false, &old_perms);
 	send_ack(conn, XS_SET_PERMS);
 
 	return 0;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index 53f1050859..eb19b71f5f 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -152,15 +152,17 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
 /* Canonicalize this path if possible. */
 char *canonicalize(struct connection *conn, const void *ctx, const char *node);
 
+/* Get access permissions. */
+enum xs_perm_type perm_for_conn(struct connection *conn,
+				const struct node_perms *perms);
+
 /* Write a node to the tdb data base. */
 int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 		   bool no_quota_check);
 
-/* Get this node, checking we have permissions. */
-struct node *get_node(struct connection *conn,
-		      const void *ctx,
-		      const char *name,
-		      enum xs_perm_type perm);
+/* Get a node from the tdb data base. */
+struct node *read_node(struct connection *conn, const void *ctx,
+		       const char *name);
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read);
 void check_store(void);
@@ -171,6 +173,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
+/* Get name of parent node. */
+char *get_parent(const void *ctx, const char *node);
+
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 7afabe0ae0..711a11b18a 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -206,7 +206,7 @@ static int destroy_domain(void *_domain)
 			unmap_interface(domain->interface);
 	}
 
-	fire_watches(NULL, domain, "@releaseDomain", false);
+	fire_watches(NULL, domain, "@releaseDomain", NULL, false, NULL);
 
 	wrl_domain_destroy(domain);
 
@@ -244,7 +244,7 @@ static void domain_cleanup(void)
 	}
 
 	if (notify)
-		fire_watches(NULL, NULL, "@releaseDomain", false);
+		fire_watches(NULL, NULL, "@releaseDomain", NULL, false, NULL);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -410,7 +410,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 		/* Now domain belongs to its connection. */
 		talloc_steal(domain->conn, domain);
 
-		fire_watches(NULL, in, "@introduceDomain", false);
+		fire_watches(NULL, in, "@introduceDomain", NULL, false, NULL);
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index e878975734..a7d8c5d475 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -114,6 +114,9 @@ struct accessed_node
 	/* Generation count (or NO_GENERATION) for conflict checking. */
 	uint64_t generation;
 
+	/* Original node permissions. */
+	struct node_perms perms;
+
 	/* Generation count checking required? */
 	bool check_gen;
 
@@ -260,6 +263,15 @@ int access_node(struct connection *conn, struct node *node,
 		i->node = talloc_strdup(i, node->name);
 		if (!i->node)
 			goto nomem;
+		if (node->generation != NO_GENERATION && node->perms.num) {
+			i->perms.p = talloc_array(i, struct xs_permissions,
+						  node->perms.num);
+			if (!i->perms.p)
+				goto nomem;
+			i->perms.num = node->perms.num;
+			memcpy(i->perms.p, node->perms.p,
+			       i->perms.num * sizeof(*i->perms.p));
+		}
 
 		introduce = true;
 		i->ta_node = false;
@@ -368,9 +380,14 @@ static int finalize_transaction(struct connection *conn,
 				talloc_free(data.dptr);
 				if (ret)
 					goto err;
-			} else if (tdb_delete(tdb_ctx, key))
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+			} else {
+				fire_watches(conn, trans, i->node, NULL, false,
+					     i->perms.p ? &i->perms : NULL);
+				if (tdb_delete(tdb_ctx, key))
 					goto err;
-			fire_watches(conn, trans, i->node, false);
+			}
 		}
 
 		if (i->ta_node && tdb_delete(tdb_ctx, ta_key))
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index f4e289362e..71c108ea99 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -85,22 +85,6 @@ static void add_event(struct connection *conn,
 	unsigned int len;
 	char *data;
 
-	if (!check_special_event(name)) {
-		/* Can this conn load node, or see that it doesn't exist? */
-		struct node *node = get_node(conn, ctx, name, XS_PERM_READ);
-		/*
-		 * XXX We allow EACCES here because otherwise a non-dom0
-		 * backend driver cannot watch for disappearance of a frontend
-		 * xenstore directory. When the directory disappears, we
-		 * revert to permissions of the parent directory for that path,
-		 * which will typically disallow access for the backend.
-		 * But this breaks device-channel teardown!
-		 * Really we should fix this better...
-		 */
-		if (!node && errno != ENOENT && errno != EACCES)
-			return;
-	}
-
 	if (watch->relative_path) {
 		name += strlen(watch->relative_path);
 		if (*name == '/') /* Could be "" */
@@ -117,12 +101,60 @@ static void add_event(struct connection *conn,
 	talloc_free(data);
 }
 
+/*
+ * Check permissions of a specific watch to fire:
+ * Either the node itself or its parent have to be readable by the connection
+ * the watch has been setup for. In case a watch event is created due to
+ * changed permissions we need to take the old permissions into account, too.
+ */
+static bool watch_permitted(struct connection *conn, const void *ctx,
+			    const char *name, struct node *node,
+			    struct node_perms *perms)
+{
+	enum xs_perm_type perm;
+	struct node *parent;
+	char *parent_name;
+
+	if (perms) {
+		perm = perm_for_conn(conn, perms);
+		if (perm & XS_PERM_READ)
+			return true;
+	}
+
+	if (!node) {
+		node = read_node(conn, ctx, name);
+		if (!node)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &node->perms);
+	if (perm & XS_PERM_READ)
+		return true;
+
+	parent = node->parent;
+	if (!parent) {
+		parent_name = get_parent(ctx, node->name);
+		if (!parent_name)
+			return false;
+		parent = read_node(conn, ctx, parent_name);
+		if (!parent)
+			return false;
+	}
+
+	perm = perm_for_conn(conn, &parent->perms);
+
+	return perm & XS_PERM_READ;
+}
+
 /*
  * Check whether any watch events are to be sent.
  * Temporary memory allocations are done with ctx.
+ * We need to take the (potential) old permissions of the node into account
+ * as a watcher losing permissions to access a node should receive the
+ * watch event, too.
  */
 void fire_watches(struct connection *conn, const void *ctx, const char *name,
-		  bool exact)
+		  struct node *node, bool exact, struct node_perms *perms)
 {
 	struct connection *i;
 	struct watch *watch;
@@ -134,8 +166,13 @@ void fire_watches(struct connection *conn, const void *ctx, const char *name,
 	/* Create an event for each watch. */
 	list_for_each_entry(i, &connections, list) {
 		/* introduce/release domain watches */
-		if (check_special_event(name) && !check_perms_special(name, i))
-			continue;
+		if (check_special_event(name)) {
+			if (!check_perms_special(name, i))
+				continue;
+		} else {
+			if (!watch_permitted(i, ctx, name, node, perms))
+				continue;
+		}
 
 		list_for_each_entry(watch, &i->watches, list) {
 			if (exact) {
diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h
index 1b3c80d3dd..03094374f3 100644
--- a/tools/xenstore/xenstored_watch.h
+++ b/tools/xenstore/xenstored_watch.h
@@ -26,7 +26,7 @@ int do_unwatch(struct connection *conn, struct buffered_data *in);
 
 /* Fire all watches: !exact means all the children are affected (ie. rm). */
 void fire_watches(struct connection *conn, const void *tmp, const char *name,
-		  bool exact);
+		  struct node *node, bool exact, struct node_perms *perms);
 
 void conn_delete_all_watches(struct connection *conn);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:12:55 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:12:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57220.100060 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60d-0006jE-Eu; Sun, 20 Dec 2020 21:12:55 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57220.100060; Sun, 20 Dec 2020 21:12:55 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60d-0006j6-Bl; Sun, 20 Dec 2020 21:12:55 +0000
Received: by outflank-mailman (input) for mailman id 57220;
 Sun, 20 Dec 2020 21:12:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60c-0006ix-57
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60c-0006SV-4P
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60c-0000jN-2x
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:12:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=Tw/Y++YCoHdW3Ydc/Xny0GLH8jFLn+Pq+aaskym1Bmk=; b=KtE59yg4wM08n6g0FlXVsOKiFE
	iVffZF/4FnfEt3LidQkICXFcBOT/9mYPujUIrgzGykQ46Bcf3zHHgwcWXoHgsVs0rl/hwHU0GxugK
	fk0AL1nX1jbhgBG48QODChCtnMt8o4gEBWYahD/1fa0G7Otcar6G0z7/zrGm1KTSzByY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: ignore transaction id for [un]watch
Message-Id: <E1kr60c-0000jN-2x@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:12:54 +0000

commit 52a0a8f6114e59753d761ea7c21552fc5370cc56
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:23 2020 +0100

    tools/ocaml/xenstored: ignore transaction id for [un]watch
    
    Instead of ignoring the transaction id for XS_WATCH and XS_UNWATCH
    commands as it is documented in docs/misc/xenstore.txt, it is tested
    for validity today.
    
    Really ignore the transaction id for XS_WATCH and XS_UNWATCH.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index ff5c9484fc..2fa6798e3b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -498,12 +498,19 @@ let retain_op_in_history ty =
 	| Xenbus.Xb.Op.Reset_watches
 	| Xenbus.Xb.Op.Invalid           -> false
 
+let maybe_ignore_transaction = function
+	| Xenbus.Xb.Op.Watch | Xenbus.Xb.Op.Unwatch -> fun tid ->
+		if tid <> Transaction.none then
+			debug "Ignoring transaction ID %d for watch/unwatch" tid;
+		Transaction.none
+	| _ -> fun x -> x
+
 (**
  * Nothrow guarantee.
  *)
 let process_packet ~store ~cons ~doms ~con ~req =
 	let ty = req.Packet.ty in
-	let tid = req.Packet.tid in
+	let tid = maybe_ignore_transaction ty req.Packet.tid in
 	let rid = req.Packet.rid in
 	try
 		let fct = function_of_type ty in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:05 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57221.100065 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60n-0006kZ-Gg; Sun, 20 Dec 2020 21:13:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57221.100065; Sun, 20 Dec 2020 21:13:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60n-0006kN-DP; Sun, 20 Dec 2020 21:13:05 +0000
Received: by outflank-mailman (input) for mailman id 57221;
 Sun, 20 Dec 2020 21:13:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60m-0006kE-8i
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60m-0006Sy-81
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60m-0000kW-6V
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bHwlITzuCw79+5Dk2aSIqwfHkcGkQdg+xV3btVwriB8=; b=iW/W1/UTfo/xM4SLXUXPtyTNAa
	g5Ran1kkIEFiu6Vi9/eLoj6aP1TMy7WrAAdvTNUDe6hBf0+7r6lb4GscS+2IX/FrG8W8t30NDg+RX
	o7tuIUptHVCzQL/1CnOBadbKFsdoFAc2KsaICSksW4Ox0GKTR7w/9ycSkTPAdG3arFro=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
Message-Id: <E1kr60m-0000kW-6V@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:04 +0000

commit b6939685484deef2b4fcdd5ca2084980544b55e4
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:28 2020 +0100

    tools/ocaml/xenstored: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for privileged
    domains only (the only user in the tree is the xenpaging daemon).
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 2fa6798e3b..fd79ef564f 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -166,7 +166,9 @@ let do_setperms con t _domains _cons data =
 let do_error _con _t _domains _cons _data =
 	raise Define.Unknown_operation
 
-let do_isintroduced _con _t domains _cons data =
+let do_isintroduced con _t domains _cons data =
+	if not (Connection.is_dom0 con)
+	then raise Define.Permission_denied;
 	let domid =
 		match (split None '\000' data) with
 		| domid :: _ -> int_of_string domid
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:15 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57222.100068 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60x-0006lr-I9; Sun, 20 Dec 2020 21:13:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57222.100068; Sun, 20 Dec 2020 21:13:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr60x-0006li-Ev; Sun, 20 Dec 2020 21:13:15 +0000
Received: by outflank-mailman (input) for mailman id 57222;
 Sun, 20 Dec 2020 21:13:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60w-0006lY-Be
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60w-0006T6-At
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr60w-0000lV-A6
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=5vbsfS7zrvDf6CUDSvqKa6xvRADRDwiZx9QTW7tvjLQ=; b=OVLCC69sUqtR9lhd/RKxLoML3r
	1bs2ZDi6OUoUXE7jdEE8lyWKRADnj3BDyiLj2G06IQDlJuFhowiAEnbmd0XWaklgZ6GQFQgsQhppx
	cFcaI/pz5IiqN0ntzTBOLMkSYL9jXq5IG3/yL5hPCDzJ5FaAehB4+18OnK+5wtPbRoTo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: unify watch firing
Message-Id: <E1kr60w-0000lV-A6@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:14 +0000

commit 2df79ff3ec66d6e877e3100cd1429199b1a03389
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:34 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:34 2020 +0100

    tools/ocaml/xenstored: unify watch firing
    
    This will make it easier insert additional checks in a follow-up patch.
    All watches are now fired from a single function.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 24750ada43..e5df62d9e7 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -210,8 +210,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	let data = Utils.join_by_null [ new_path; watch.token; "" ] in
-	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
+	fire_single_watch { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:25 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57223.100072 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr617-0006n5-Ji; Sun, 20 Dec 2020 21:13:25 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57223.100072; Sun, 20 Dec 2020 21:13:25 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr617-0006mw-GP; Sun, 20 Dec 2020 21:13:25 +0000
Received: by outflank-mailman (input) for mailman id 57223;
 Sun, 20 Dec 2020 21:13:24 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr616-0006mm-EO
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr616-0006TH-Dg
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr616-0000mR-D1
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+wo+2zVTwMUK+dYdLg+zfyEIYQLjC3OzPcbD92v6kIY=; b=P9Lw0OgJFxySKC/b5SCewNqOEf
	Fw0/SJIY/nk0raYuvbNAC1TRTvj449fgmqkjl3W9pICplS0LRJW2p8YdxdxfGWMJO+tUVzJ/XEj7M
	II+b0fNxnPOEgRrJl8k5ML7A7bnpDQaoxEF54xdK3JFN8Oz35cK4Hm8MOOD7Swyr6pcs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: introduce permissions for special watches
Message-Id: <E1kr616-0000mR-D1@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:24 +0000

commit 65c187f935c0e616424760b01e22c7b713f0907d
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:39 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:39 2020 +0100

    tools/ocaml/xenstored: introduce permissions for special watches
    
    The special watches "@introduceDomain" and "@releaseDomain" should be
    allowed for privileged callers only, as they allow to gain information
    about presence of other guests on the host. So send watch events for
    those watches via privileged connections only.
    
    Start to address this by treating the special watches as regular nodes
    in the tree, which gives them normal semantics for permissions.  A later
    change will restrict the handling, so that they can't be listed, etc.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/process.ml   |  4 ++--
 tools/ocaml/xenstored/store.ml     |  5 +++++
 tools/ocaml/xenstored/utils.ml     | 26 ++++++++++++--------------
 tools/ocaml/xenstored/xenstored.ml |  4 +++-
 4 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index fd79ef564f..e528d1ecb2 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -420,7 +420,7 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons "@introduceDomain";
+			Connections.fire_spec_watches cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
@@ -439,7 +439,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons "@releaseDomain"
+	then Connections.fire_spec_watches cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 92b6289b5e..52b88b3ee1 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -214,6 +214,11 @@ let rec lookup node path fct =
 
 let apply rnode path fct =
 	lookup rnode path fct
+
+let introduce_domain = "@introduceDomain"
+let release_domain = "@releaseDomain"
+let specials = List.map of_string [ introduce_domain; release_domain ]
+
 end
 
 (* The Store.t type *)
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index b252db799b..e8c9fe4e94 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -88,19 +88,17 @@ let read_file_single_integer filename =
 	Unix.close fd;
 	int_of_string (Bytes.sub_string buf 0 sz)
 
-let path_complete path connection_path =
-	if String.get path 0 <> '/' then
-		connection_path ^ path
-	else
-		path
-
+(* @path may be guest data and needs its length validating.  @connection_path
+ * is generated locally in xenstored and always of the form "/local/domain/$N/" *)
 let path_validate path connection_path =
-	if String.length path = 0 || String.length path > 1024 then
-		raise Define.Invalid_path
-	else
-		let cpath = path_complete path connection_path in
-		if String.get cpath 0 <> '/' then
-			raise Define.Invalid_path
-		else
-			cpath
+	let len = String.length path in
+
+	if len = 0 || len > 1024 then raise Define.Invalid_path;
+
+	let abs_path =
+		match String.get path 0 with
+		| '/' | '@' -> path
+		| _   -> connection_path ^ path
+	in
 
+	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a4466c5b5c..894e5a709d 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -287,6 +287,8 @@ let _ =
 	let quit = ref false in
 
 	Logging.init_xenstored_log();
+	List.iter (fun path ->
+		Store.write store Perms.Connection.full_rights path "") Store.Path.specials;
 
 	let filename = Paths.xen_run_stored ^ "/db" in
 	if cf.restart && Sys.file_exists filename then (
@@ -339,7 +341,7 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons "@releaseDomain"
+						Connections.fire_spec_watches cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:35 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57224.100076 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61H-0006oV-Mg; Sun, 20 Dec 2020 21:13:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57224.100076; Sun, 20 Dec 2020 21:13:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61H-0006oL-JS; Sun, 20 Dec 2020 21:13:35 +0000
Received: by outflank-mailman (input) for mailman id 57224;
 Sun, 20 Dec 2020 21:13:34 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61G-0006oB-HG
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:34 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61G-0006TO-GZ
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:34 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61G-0000nH-Fr
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:34 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=wzS3XBintuqeZZyIBkBp9pYDwQP3BwJ1hzPdCUyTFOs=; b=ZudBW6OCos5WKaRWucaAykmE5l
	tcwrNu38U1VieogSy3ddyFeQ2FZNVDk9eyu/P7b7H+UWhug6tlapvRCTLhtpEu3/Pax65EigYslrh
	ao0FeO21MGpAAp9ePl6JxgVN77hV6Hjgv/y7oqJR3A3FPJAIOwn6Yp0fiMEkujKtDj0g=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: avoid watch events for nodes without access
Message-Id: <E1kr61G-0000nH-Fr@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:34 +0000

commit f4d84a2481baf1aab9937db88af9b72e172a4a6f
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:44 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:44 2020 +0100

    tools/ocaml/xenstored: avoid watch events for nodes without access
    
    Today watch events are sent regardless of the access rights of the
    node the event is sent for. This enables any guest to e.g. setup a
    watch for "/" in order to have a detailed record of all Xenstore
    modifications.
    
    Modify that by sending only watch events for nodes that the watcher
    has a chance to see otherwise (either via direct reads or by querying
    the children of a node). This includes cases where the visibility of
    a node for a watcher is changing (permissions being removed).
    
    Permissions for nodes are looked up either in the old (pre
    transaction/command) or current trees (post transaction).  If
    permissions are changed multiple times in a transaction only the final
    version is checked, because considering a transaction atomic the
    individual permission changes would not be noticable to an outside
    observer.
    
    Two trees are only needed for set_perms: here we can either notice the
    node disappearing (if we loose permission), appearing
    (if we gain permission), or changing (if we preserve permission).
    
    RM needs to only look at the old tree: in the new tree the node would be
    gone, or could have different permissions if it was recreated (the
    recreation would get its own watch fired).
    
    Inside a tree we lookup the watch path's parent, and then the watch path
    child itself.  This gets us 4 sets of permissions in worst case, and if
    either of these allows a watch, then we permit it to fire.  The
    permission lookups are done without logging the failures, otherwise we'd
    get confusing errors about permission denied for some paths, but a watch
    still firing. The actual result is logged in xenstored-access log:
    
      'w event ...' as usual if watch was fired
      'w notfired...' if the watch was not fired, together with path and
      permission set to help in troubleshooting
    
    Adding a watch bypasses permission checks and always fires the watch
    once immediately. This is consistent with the specification, and no
    information is gained (the watch is fired both if the path exists or
    doesn't, and both if you have or don't have access, i.e. it reflects the
    path a domain gave it back to that domain).
    
    There are some semantic changes here:
    
      * Write+rm in a single transaction of the same path is unobservable
        now via watches: both before and after a transaction the path
        doesn't exist, thus both tree lookups come up with the empty
        permission set, and noone, not even Dom0 can see this. This is
        consistent with transaction atomicity though.
      * Similar to above if we temporarily grant and then revoke permission
        on a path any watches fired inbetween are ignored as well
      * There is a new log event (w notfired) which shows the permission set
        of the path, and the path.
      * Watches on paths that a domain doesn't have access to are now not
        seen, which is the purpose of the security fix.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml  | 31 +++++++++++++++++++++++++---
 tools/ocaml/xenstored/connections.ml | 11 +++++-----
 tools/ocaml/xenstored/logging.ml     |  8 ++++++++
 tools/ocaml/xenstored/perms.ml       | 18 +++++++++++-----
 tools/ocaml/xenstored/process.ml     | 40 +++++++++++++++++++++---------------
 tools/ocaml/xenstored/transaction.ml |  4 ++++
 tools/ocaml/xenstored/xenstored.ml   |  4 +++-
 7 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index e5df62d9e7..644a448f2e 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -196,11 +196,36 @@ let list_watches con =
 		con.watches [] in
 	List.concat ll
 
-let fire_single_watch watch =
+let dbg fmt = Logging.debug "connection" fmt
+let info fmt = Logging.info "connection" fmt
+
+let lookup_watch_perm path = function
+| None -> []
+| Some root ->
+	try Store.Path.apply root path @@ fun parent name ->
+		Store.Node.get_perms parent ::
+		try [Store.Node.get_perms (Store.Node.find parent name)]
+		with Not_found -> []
+	with Define.Invalid_path | Not_found -> []
+
+let lookup_watch_perms oldroot root path =
+	lookup_watch_perm path oldroot @ lookup_watch_perm path (Some root)
+
+let fire_single_watch_unchecked watch =
 	let data = Utils.join_by_null [watch.path; watch.token; ""] in
 	send_reply watch.con Transaction.none 0 Xenbus.Xb.Op.Watchevent data
 
-let fire_watch watch path =
+let fire_single_watch (oldroot, root) watch =
+	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
+	let perms = lookup_watch_perms oldroot root abspath in
+	if List.exists (Perms.has watch.con.perm READ) perms then
+		fire_single_watch_unchecked watch
+	else
+		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
+		let con = get_domstr watch.con in
+		Logging.watch_not_fired ~con perms (Store.Path.to_string abspath)
+
+let fire_watch roots watch path =
 	let new_path =
 		if watch.is_relative && path.[0] = '/'
 		then begin
@@ -210,7 +235,7 @@ let fire_watch watch path =
 		end else
 			path
 	in
-	fire_single_watch { watch with path = new_path }
+	fire_single_watch roots { watch with path = new_path }
 
 (* Search for a valid unused transaction id. *)
 let rec valid_transaction_id con proposed_id =
diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index f02ef6b526..834955fb08 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -135,25 +135,26 @@ let del_watch cons con path token =
  	watch
 
 (* path is absolute *)
-let fire_watches cons path recurse =
+let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
 	let path = Store.Path.to_string path in
+	let roots = oldroot, root in
 	let fire_watch _ = function
 		| None         -> ()
-		| Some watches -> List.iter (fun w -> Connection.fire_watch w path) watches
+		| Some watches -> List.iter (fun w -> Connection.fire_watch roots w path) watches
 	in
 	let fire_rec _x = function
 		| None         -> ()
 		| Some watches ->
-			  List.iter (fun w -> Connection.fire_single_watch w) watches
+			List.iter (Connection.fire_single_watch roots) watches
 	in
 	Trie.iter_path fire_watch cons.watches key;
 	if recurse then
 		Trie.iter fire_rec (Trie.sub cons.watches key)
 
-let fire_spec_watches cons specpath =
+let fire_spec_watches root cons specpath =
 	iter cons (fun con ->
-		List.iter (fun w -> Connection.fire_single_watch w) (Connection.get_watches con specpath))
+		List.iter (Connection.fire_single_watch (None, root)) (Connection.get_watches con specpath))
 
 let set_target cons domain target_domain =
 	let con = find_domain cons domain in
diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml
index c5cba79e92..1ede131329 100644
--- a/tools/ocaml/xenstored/logging.ml
+++ b/tools/ocaml/xenstored/logging.ml
@@ -161,6 +161,8 @@ let xenstored_log_nb_lines = ref 13215
 let xenstored_log_nb_chars = ref (-1)
 let xenstored_logger = ref (None: logger option)
 
+let debug_enabled () = !xenstored_log_level = Debug
+
 let set_xenstored_log_destination s =
 	xenstored_log_destination := log_destination_of_string s
 
@@ -204,6 +206,7 @@ type access_type =
 	| Commit
 	| Newconn
 	| Endconn
+	| Watch_not_fired
 	| XbOp of Xenbus.Xb.Op.operation
 
 let string_of_tid ~con tid =
@@ -217,6 +220,7 @@ let string_of_access_type = function
 	| Commit                  -> "commit   "
 	| Newconn                 -> "newconn  "
 	| Endconn                 -> "endconn  "
+	| Watch_not_fired         -> "w notfired"
 
 	| XbOp op -> match op with
 	| Xenbus.Xb.Op.Debug             -> "debug    "
@@ -331,3 +335,7 @@ let xb_answer ~tid ~con ~ty data =
 		| _ -> false, Debug
 	in
 	if print then access_logging ~tid ~con ~data (XbOp ty) ~level
+
+let watch_not_fired ~con perms path =
+	let data = Printf.sprintf "EPERM perms=[%s] path=%s" perms path in
+	access_logging ~tid:0 ~con ~data Watch_not_fired ~level:Info
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 3ea193ea14..23b80aba3d 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -79,9 +79,9 @@ let of_string s =
 let string_of_perm perm =
 	Printf.sprintf "%c%u" (char_of_permty (snd perm)) (fst perm)
 
-let to_string permvec =
+let to_string ?(sep="\000") permvec =
 	let l = ((permvec.owner, permvec.other) :: permvec.acl) in
-	String.concat "\000" (List.map string_of_perm l)
+	String.concat sep (List.map string_of_perm l)
 
 end
 
@@ -132,8 +132,8 @@ let check_owner (connection:Connection.t) (node:Node.t) =
 	then Connection.is_owner connection (Node.get_owner node)
 	else true
 
-(* check if the current connection has the requested perm on the current node *)
-let check (connection:Connection.t) request (node:Node.t) =
+(* check if the current connection lacks the requested perm on the current node *)
+let lacks (connection:Connection.t) request (node:Node.t) =
 	let check_acl domainid =
 		let perm =
 			if List.mem_assoc domainid (Node.get_acl node)
@@ -154,11 +154,19 @@ let check (connection:Connection.t) request (node:Node.t) =
 			info "Permission denied: Domain %d has write only access" domainid;
 			false
 	in
-	if !activate
+	!activate
 	&& not (Connection.is_dom0 connection)
 	&& not (check_owner connection node)
 	&& not (List.exists check_acl (Connection.get_owners connection))
+
+(* check if the current connection has the requested perm on the current node.
+*  Raises an exception if it doesn't. *)
+let check connection request node =
+	if lacks connection request node
 	then raise Define.Permission_denied
 
+(* check if the current connection has the requested perm on the current node *)
+let has connection request node = not (lacks connection request node)
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index e528d1ecb2..f99b9e935c 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -56,15 +56,17 @@ let split_one_path data con =
 	| path :: "" :: [] -> Store.Path.create path (Connection.get_path con)
 	| _                -> raise Invalid_Cmd_Args
 
-let process_watch ops cons =
+let process_watch t cons =
+	let oldroot = t.Transaction.oldroot in
+	let newroot = Store.get_root t.store in
+	let ops = Transaction.get_paths t |> List.rev in
 	let do_op_watch op cons =
-		let recurse = match (fst op) with
-		| Xenbus.Xb.Op.Write    -> false
-		| Xenbus.Xb.Op.Mkdir    -> false
-		| Xenbus.Xb.Op.Rm       -> true
-		| Xenbus.Xb.Op.Setperms -> false
+		let recurse, oldroot, root = match (fst op) with
+		| Xenbus.Xb.Op.Write|Xenbus.Xb.Op.Mkdir -> false, None, newroot
+		| Xenbus.Xb.Op.Rm       -> true, None, oldroot
+		| Xenbus.Xb.Op.Setperms -> false, Some oldroot, newroot
 		| _              -> raise (Failure "huh ?") in
-		Connections.fire_watches cons (snd op) recurse in
+		Connections.fire_watches ?oldroot root cons (snd op) recurse in
 	List.iter (fun op -> do_op_watch op cons) ops
 
 let create_implicit_path t perm path =
@@ -205,7 +207,7 @@ let reply_ack fct con t doms cons data =
 	fct con t doms cons data;
 	Packet.Ack (fun () ->
 		if Transaction.get_id t = Transaction.none then
-			process_watch (Transaction.get_paths t) cons
+			process_watch t cons
 	)
 
 let reply_data fct con t doms cons data =
@@ -353,14 +355,17 @@ let transaction_replay c t doms cons =
 			ignore @@ Connection.end_transaction c tid None
 		)
 
-let do_watch con _t _domains cons data =
+let do_watch con t _domains cons data =
 	let (node, token) =
 		match (split None '\000' data) with
 		| [node; token; ""]   -> node, token
 		| _                   -> raise Invalid_Cmd_Args
 		in
 	let watch = Connections.add_watch cons con node token in
-	Packet.Ack (fun () -> Connection.fire_single_watch watch)
+	Packet.Ack (fun () ->
+		(* xenstore.txt says this watch is fired immediately,
+		   implying even if path doesn't exist or is unreadable *)
+		Connection.fire_single_watch_unchecked watch)
 
 let do_unwatch con _t _domains cons data =
 	let (node, token) =
@@ -391,7 +396,7 @@ let do_transaction_end con t domains cons data =
 	if not success then
 		raise Transaction_again;
 	if commit then begin
-		process_watch (List.rev (Transaction.get_paths t)) cons;
+		process_watch t cons;
 		match t.Transaction.ty with
 		| Transaction.No ->
 			() (* no need to record anything *)
@@ -399,7 +404,7 @@ let do_transaction_end con t domains cons data =
 			record_commit ~con ~tid:id ~before:oldstore ~after:cstore
 	end
 
-let do_introduce con _t domains cons data =
+let do_introduce con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let (domid, mfn, port) =
@@ -420,14 +425,14 @@ let do_introduce con _t domains cons data =
 		else try
 			let ndom = Domains.create domains domid mfn port in
 			Connections.add_domain cons ndom;
-			Connections.fire_spec_watches cons Store.Path.introduce_domain;
+			Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.introduce_domain;
 			ndom
 		with _ -> raise Invalid_Cmd_Args
 	in
 	if (Domain.get_remote_port dom) <> port || (Domain.get_mfn dom) <> mfn then
 		raise Domain_not_match
 
-let do_release con _t domains cons data =
+let do_release con t domains cons data =
 	if not (Connection.is_dom0 con)
 	then raise Define.Permission_denied;
 	let domid =
@@ -439,7 +444,7 @@ let do_release con _t domains cons data =
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
 	if fire_spec_watches
-	then Connections.fire_spec_watches cons Store.Path.release_domain
+	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
 
 let do_resume con _t domains _cons data =
@@ -507,6 +512,8 @@ let maybe_ignore_transaction = function
 		Transaction.none
 	| _ -> fun x -> x
 
+
+let () = Printexc.record_backtrace true
 (**
  * Nothrow guarantee.
  *)
@@ -548,7 +555,8 @@ let process_packet ~store ~cons ~doms ~con ~req =
 		(* Put the response on the wire *)
 		send_response ty con t rid response
 	with exn ->
-		error "process packet: %s" (Printexc.to_string exn);
+		let bt = Printexc.get_backtrace () in
+		error "process packet: %s. %s" (Printexc.to_string exn) bt;
 		Connection.send_error con tid rid "EIO"
 
 let do_input store cons doms con =
diff --git a/tools/ocaml/xenstored/transaction.ml b/tools/ocaml/xenstored/transaction.ml
index 963734a653..25bc8c3b4a 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -82,6 +82,7 @@ type t = {
 	start_count: int64;
 	store: Store.t; (* This is the store that we change in write operations. *)
 	quota: Quota.t;
+	oldroot: Store.Node.t;
 	mutable paths: (Xenbus.Xb.Op.operation * Store.Path.t) list;
 	mutable operations: (Packet.request * Packet.response) list;
 	mutable read_lowpath: Store.Path.t option;
@@ -123,6 +124,7 @@ let make ?(internal=false) id store =
 		start_count = !counter;
 		store = if id = none then store else Store.copy store;
 		quota = Quota.copy store.Store.quota;
+		oldroot = Store.get_root store;
 		paths = [];
 		operations = [];
 		read_lowpath = None;
@@ -137,6 +139,8 @@ let make ?(internal=false) id store =
 let get_store t = t.store
 let get_paths t = t.paths
 
+let get_root t = Store.get_root t.store
+
 let is_read_only t = t.paths = []
 let add_wop t ty path = t.paths <- (ty, path) :: t.paths
 let add_operation ~perm t request response =
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 894e5a709d..a7b837c19c 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -341,7 +341,9 @@ let _ =
 					let (notify, deaddom) = Domains.cleanup domains in
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
-						Connections.fire_spec_watches cons Store.Path.release_domain
+						Connections.fire_spec_watches
+							(Store.get_root store)
+							cons Store.Path.release_domain
 				)
 				else
 					let c = Connections.find_domain_by_port cons port in
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:45 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:45 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57225.100081 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61R-0006pm-OQ; Sun, 20 Dec 2020 21:13:45 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57225.100081; Sun, 20 Dec 2020 21:13:45 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61R-0006pa-L0; Sun, 20 Dec 2020 21:13:45 +0000
Received: by outflank-mailman (input) for mailman id 57225;
 Sun, 20 Dec 2020 21:13:44 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61Q-0006pT-K4
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:44 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61Q-0006Td-JP
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:44 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61Q-0000o8-Id
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:44 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=lCc+dmRaVZoeQ1bwfL7DcjO88fo3hP59dSflyGpNOXs=; b=IXaOm9jgeoJnm60J4gFl46zVjE
	0LdXFC5W/RHXevvK//TWOZ0s98Kc9skzA9R5DF1WV8jmKxgX1wMfdldaZ1kraZKPT+0OUdCHinXvq
	vi33/FaqyGwi8365/xNgnlWZjWWqe3vozq9bti+5MND9tIvqF00ERM/WwCzVAUfu360E=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
Message-Id: <E1kr61Q-0000o8-Id@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:44 +0000

commit 4056c3e6682ff8eea9fc4014648acfeb755a9e64
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:19:50 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:19:50 2020 +0100

    tools/ocaml/xenstored: add xenstored.conf flag to turn off watch permission checks
    
    There are flags to turn off quotas and the permission system, so add one
    that turns off the newly introduced watch permission checks as well.
    
    This is part of XSA-115.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connection.ml      |  2 +-
 tools/ocaml/xenstored/oxenstored.conf.in | 10 ++++++++++
 tools/ocaml/xenstored/perms.ml           |  5 +++++
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 644a448f2e..fa0d3c4d92 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -218,7 +218,7 @@ let fire_single_watch_unchecked watch =
 let fire_single_watch (oldroot, root) watch =
 	let abspath = get_watch_path watch.con watch.path |> Store.Path.of_string in
 	let perms = lookup_watch_perms oldroot root abspath in
-	if List.exists (Perms.has watch.con.perm READ) perms then
+	if Perms.can_fire_watch watch.con.perm perms then
 		fire_single_watch_unchecked watch
 	else
 		let perms = perms |> List.map (Perms.Node.to_string ~sep:" ") |> String.concat ", " in
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index 151b65b72d..f843482981 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -44,6 +44,16 @@ conflict-rate-limit-is-aggregate = true
 # Activate node permission system
 perms-activate = true
 
+# Activate the watch permission system
+# When this is enabled unprivileged guests can only get watch events
+# for xenstore entries that they would've been able to read.
+#
+# When this is disabled unprivileged guests may get watch events
+# for xenstore entries that they cannot read. The watch event contains
+# only the entry name, not the value.
+# This restores behaviour prior to XSA-115.
+perms-watch-activate = true
+
 # Activate quota
 quota-activate = true
 quota-maxentity = 1000
diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index 23b80aba3d..ee7fee6bda 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -20,6 +20,7 @@ let info fmt = Logging.info "perms" fmt
 open Stdext
 
 let activate = ref true
+let watch_activate = ref true
 
 type permty = READ | WRITE | RDWR | NONE
 
@@ -168,5 +169,9 @@ let check connection request node =
 (* check if the current connection has the requested perm on the current node *)
 let has connection request node = not (lacks connection request node)
 
+let can_fire_watch connection perms =
+	not !watch_activate
+	|| List.exists (has connection READ) perms
+
 let equiv perm1 perm2 =
 	(Node.to_string perm1) = (Node.to_string perm2)
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a7b837c19c..6926a4de41 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -95,6 +95,7 @@ let parse_config filename =
 		("conflict-max-history-seconds", Config.Set_float Define.conflict_max_history_seconds);
 		("conflict-rate-limit-is-aggregate", Config.Set_bool Define.conflict_rate_limit_is_aggregate);
 		("perms-activate", Config.Set_bool Perms.activate);
+		("perms-watch-activate", Config.Set_bool Perms.watch_activate);
 		("quota-activate", Config.Set_bool Quota.activate);
 		("quota-maxwatch", Config.Set_int Define.maxwatch);
 		("quota-transaction", Config.Set_int Define.maxtransaction);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:13:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:13:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57226.100083 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61c-0006rM-Pv; Sun, 20 Dec 2020 21:13:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57226.100083; Sun, 20 Dec 2020 21:13:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61c-0006rE-Mg; Sun, 20 Dec 2020 21:13:56 +0000
Received: by outflank-mailman (input) for mailman id 57226;
 Sun, 20 Dec 2020 21:13:54 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61a-0006r2-NF
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:54 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61a-0006U3-MU
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:54 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61a-0000ov-Ln
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:13:54 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=EvoDlFQ7U0viCquNCsbxmEtPg5HJsB/A3B7LIDxcJQw=; b=TF2tOGpPjQwib8kRArGoJa9ul4
	r8B9auxeZZT+cQVaCZkwJC6suUlep9sCU/UggW89n7k66WECxtAhWkSDIWJqnHxK4LPTIWDpsuRRC
	Vx7V5jQG1UycMfgp1+GtKdeWdvYKkUSJz6GeY6G5a3i27RIF8Uh6jOvnyK7IIkpov+zQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: revoke access rights for removed domains
Message-Id: <E1kr61a-0000ov-Ln@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:13:54 +0000

commit 12a41a8072a7fc75e58083c0d3bf55200d578bef
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:20:24 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:20:24 2020 +0100

    tools/xenstore: revoke access rights for removed domains
    
    Access rights of Xenstore nodes are per domid. Unfortunately existing
    granted access rights are not removed when a domain is being destroyed.
    This means that a new domain created with the same domid will inherit
    the access rights to Xenstore nodes from the previous domain(s) with
    the same domid.
    
    This can be avoided by adding a generation counter to each domain.
    The generation counter of the domain is set to the global generation
    counter when a domain structure is being allocated. When reading or
    writing a node all permissions of domains which are younger than the
    node itself are dropped. This is done by flagging the related entry
    as invalid in order to avoid modifying permissions in a way the user
    could detect.
    
    A special case has to be considered: for a new domain the first
    Xenstore entries are already written before the domain is officially
    introduced in Xenstore. In order not to drop the permissions for the
    new domain a domain struct is allocated even before introduction if
    the hypervisor is aware of the domain. This requires adding another
    bool "introduced" to struct domain in xenstored. In order to avoid
    additional padding holes convert the shutdown flag to bool, too.
    
    As verifying permissions has its price regarding runtime add a new
    quota for limiting the number of permissions an unprivileged domain
    can set for a node. The default for that new quota is 5.
    
    This is part of XSA-322.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
    Acked-by: Julien Grall <julien@amazon.com>
---
 tools/xenstore/include/xenstore_lib.h  |   1 +
 tools/xenstore/xenstored_core.c        |  29 ++++-
 tools/xenstore/xenstored_domain.c      | 186 ++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_domain.h      |   3 +
 tools/xenstore/xenstored_transaction.c |  15 ++-
 tools/xenstore/xenstored_transaction.h |   2 +
 tools/xenstore/xs_lib.c                |   2 +-
 7 files changed, 192 insertions(+), 46 deletions(-)

diff --git a/tools/xenstore/include/xenstore_lib.h b/tools/xenstore/include/xenstore_lib.h
index 0ffbae9eb5..4c9b6d1685 100644
--- a/tools/xenstore/include/xenstore_lib.h
+++ b/tools/xenstore/include/xenstore_lib.h
@@ -34,6 +34,7 @@ enum xs_perm_type {
 	/* Internal use. */
 	XS_PERM_ENOENT_OK = 4,
 	XS_PERM_OWNER = 8,
+	XS_PERM_IGNORE = 16,
 };
 
 struct xs_permissions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 1c28454545..cb2c70bfe7 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -101,6 +101,7 @@ int quota_nb_entry_per_domain = 1000;
 int quota_nb_watch_per_domain = 128;
 int quota_max_entry_size = 2048; /* 2K */
 int quota_max_transaction = 10;
+int quota_nb_perms_per_node = 5;
 
 void trace(const char *fmt, ...)
 {
@@ -407,8 +408,13 @@ struct node *read_node(struct connection *conn, const void *ctx,
 
 	/* Permissions are struct xs_permissions. */
 	node->perms.p = hdr->perms;
+	if (domain_adjust_node_perms(node)) {
+		talloc_free(node);
+		return NULL;
+	}
+
 	/* Data is binary blob (usually ascii, no nul). */
-	node->data = node->perms.p + node->perms.num;
+	node->data = node->perms.p + hdr->num_perms;
 	/* Children is strings, nul separated. */
 	node->children = node->data + node->datalen;
 
@@ -424,6 +430,9 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
 	void *p;
 	struct xs_tdb_record_hdr *hdr;
 
+	if (domain_adjust_node_perms(node))
+		return errno;
+
 	data.dsize = sizeof(*hdr)
 		+ node->perms.num * sizeof(node->perms.p[0])
 		+ node->datalen + node->childlen;
@@ -483,8 +492,9 @@ enum xs_perm_type perm_for_conn(struct connection *conn,
 		return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
 	for (i = 1; i < perms->num; i++)
-		if (perms->p[i].id == conn->id
-                        || (conn->target && perms->p[i].id == conn->target->id))
+		if (!(perms->p[i].perms & XS_PERM_IGNORE) &&
+		    (perms->p[i].id == conn->id ||
+		     (conn->target && perms->p[i].id == conn->target->id)))
 			return perms->p[i].perms & mask;
 
 	return perms->p[0].perms & mask;
@@ -1246,8 +1256,12 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
 	if (perms.num < 2)
 		return EINVAL;
 
-	permstr = in->buffer + strlen(in->buffer) + 1;
 	perms.num--;
+	if (domain_is_unprivileged(conn) &&
+	    perms.num > quota_nb_perms_per_node)
+		return ENOSPC;
+
+	permstr = in->buffer + strlen(in->buffer) + 1;
 
 	perms.p = talloc_array(in, struct xs_permissions, perms.num);
 	if (!perms.p)
@@ -1919,6 +1933,7 @@ static void usage(void)
 "  -S, --entry-size <size> limit the size of entry per domain, and\n"
 "  -W, --watch-nb <nb>     limit the number of watches per domain,\n"
 "  -t, --transaction <nb>  limit the number of transaction allowed per domain,\n"
+"  -A, --perm-nb <nb>      limit the number of permissions per node,\n"
 "  -R, --no-recovery       to request that no recovery should be attempted when\n"
 "                          the store is corrupted (debug only),\n"
 "  -I, --internal-db       store database in memory, not on disk\n"
@@ -1939,6 +1954,7 @@ static struct option options[] = {
 	{ "entry-size", 1, NULL, 'S' },
 	{ "trace-file", 1, NULL, 'T' },
 	{ "transaction", 1, NULL, 't' },
+	{ "perm-nb", 1, NULL, 'A' },
 	{ "no-recovery", 0, NULL, 'R' },
 	{ "internal-db", 0, NULL, 'I' },
 	{ "verbose", 0, NULL, 'V' },
@@ -1961,7 +1977,7 @@ int main(int argc, char *argv[])
 	int timeout;
 
 
-	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RVW:", options,
+	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:T:RVW:", options,
 				  NULL)) != -1) {
 		switch (opt) {
 		case 'D':
@@ -2003,6 +2019,9 @@ int main(int argc, char *argv[])
 		case 'W':
 			quota_nb_watch_per_domain = strtol(optarg, NULL, 10);
 			break;
+		case 'A':
+			quota_nb_perms_per_node = strtol(optarg, NULL, 10);
+			break;
 		case 'e':
 			dom0_event = strtol(optarg, NULL, 10);
 			break;
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 711a11b18a..2a02b22933 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -71,8 +71,14 @@ struct domain
 	/* The connection associated with this. */
 	struct connection *conn;
 
+	/* Generation count at domain introduction time. */
+	uint64_t generation;
+
 	/* Have we noticed that this domain is shutdown? */
-	int shutdown;
+	bool shutdown;
+
+	/* Has domain been officially introduced? */
+	bool introduced;
 
 	/* number of entry from this domain in the store */
 	int nbentry;
@@ -192,6 +198,9 @@ static int destroy_domain(void *_domain)
 
 	list_del(&domain->list);
 
+	if (!domain->introduced)
+		return 0;
+
 	if (domain->port) {
 		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
@@ -213,21 +222,34 @@ static int destroy_domain(void *_domain)
 	return 0;
 }
 
+static bool get_domain_info(unsigned int domid, xc_dominfo_t *dominfo)
+{
+	return xc_domain_getinfo(*xc_handle, domid, 1, dominfo) == 1 &&
+	       dominfo->domid == domid;
+}
+
 static void domain_cleanup(void)
 {
 	xc_dominfo_t dominfo;
 	struct domain *domain;
 	struct connection *conn;
 	int notify = 0;
+	bool dom_valid;
 
  again:
 	list_for_each_entry(domain, &domains, list) {
-		if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
-				      &dominfo) == 1 &&
-		    dominfo.domid == domain->domid) {
+		dom_valid = get_domain_info(domain->domid, &dominfo);
+		if (!domain->introduced) {
+			if (!dom_valid) {
+				talloc_free(domain);
+				goto again;
+			}
+			continue;
+		}
+		if (dom_valid) {
 			if ((dominfo.crashed || dominfo.shutdown)
 			    && !domain->shutdown) {
-				domain->shutdown = 1;
+				domain->shutdown = true;
 				notify = 1;
 			}
 			if (!dominfo.dying)
@@ -293,58 +315,84 @@ static char *talloc_domain_path(void *context, unsigned int domid)
 	return talloc_asprintf(context, "/local/domain/%u", domid);
 }
 
-static struct domain *new_domain(void *context, unsigned int domid,
-				 int port)
+static struct domain *find_domain_struct(unsigned int domid)
+{
+	struct domain *i;
+
+	list_for_each_entry(i, &domains, list) {
+		if (i->domid == domid)
+			return i;
+	}
+	return NULL;
+}
+
+static struct domain *alloc_domain(void *context, unsigned int domid)
 {
 	struct domain *domain;
-	int rc;
 
 	domain = talloc(context, struct domain);
-	if (!domain)
+	if (!domain) {
+		errno = ENOMEM;
 		return NULL;
+	}
 
-	domain->port = 0;
-	domain->shutdown = 0;
 	domain->domid = domid;
-	domain->path = talloc_domain_path(domain, domid);
-	if (!domain->path)
-		return NULL;
+	domain->generation = generation;
+	domain->introduced = false;
 
-	wrl_domain_new(domain);
+	talloc_set_destructor(domain, destroy_domain);
 
 	list_add(&domain->list, &domains);
-	talloc_set_destructor(domain, destroy_domain);
+
+	return domain;
+}
+
+static int new_domain(struct domain *domain, int port)
+{
+	int rc;
+
+	domain->port = 0;
+	domain->shutdown = false;
+	domain->path = talloc_domain_path(domain, domain->domid);
+	if (!domain->path) {
+		errno = ENOMEM;
+		return errno;
+	}
+
+	wrl_domain_new(domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domain->domid, port);
 	if (rc == -1)
-	    return NULL;
+		return errno;
 	domain->port = rc;
 
+	domain->introduced = true;
+
 	domain->conn = new_connection(writechn, readchn);
-	if (!domain->conn)
-		return NULL;
+	if (!domain->conn)  {
+		errno = ENOMEM;
+		return errno;
+	}
 
 	domain->conn->domain = domain;
-	domain->conn->id = domid;
+	domain->conn->id = domain->domid;
 
 	domain->remote_port = port;
 	domain->nbentry = 0;
 	domain->nbwatch = 0;
 
-	return domain;
+	return 0;
 }
 
 
 static struct domain *find_domain_by_domid(unsigned int domid)
 {
-	struct domain *i;
+	struct domain *d;
 
-	list_for_each_entry(i, &domains, list) {
-		if (i->domid == domid)
-			return i;
-	}
-	return NULL;
+	d = find_domain_struct(domid);
+
+	return (d && d->introduced) ? d : NULL;
 }
 
 static void domain_conn_reset(struct domain *domain)
@@ -391,15 +439,21 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
 	if (port <= 0)
 		return EINVAL;
 
-	domain = find_domain_by_domid(domid);
+	domain = find_domain_struct(domid);
 
 	if (domain == NULL) {
+		/* Hang domain off "in" until we're finished. */
+		domain = alloc_domain(in, domid);
+		if (domain == NULL)
+			return ENOMEM;
+	}
+
+	if (!domain->introduced) {
 		interface = map_interface(domid);
 		if (!interface)
 			return errno;
 		/* Hang domain off "in" until we're finished. */
-		domain = new_domain(in, domid, port);
-		if (!domain) {
+		if (new_domain(domain, port)) {
 			rc = errno;
 			unmap_interface(interface);
 			return rc;
@@ -510,8 +564,8 @@ int do_resume(struct connection *conn, struct buffered_data *in)
 	if (IS_ERR(domain))
 		return -PTR_ERR(domain);
 
-	domain->shutdown = 0;
-	
+	domain->shutdown = false;
+
 	send_ack(conn, XS_RESUME);
 
 	return 0;
@@ -654,8 +708,10 @@ static int dom0_init(void)
 	if (port == -1)
 		return -1;
 
-	dom0 = new_domain(NULL, xenbus_master_domid(), port);
-	if (dom0 == NULL)
+	dom0 = alloc_domain(NULL, xenbus_master_domid());
+	if (!dom0)
+		return -1;
+	if (new_domain(dom0, port))
 		return -1;
 
 	dom0->interface = xenbus_map();
@@ -736,6 +792,66 @@ void domain_entry_inc(struct connection *conn, struct node *node)
 	}
 }
 
+/*
+ * Check whether a domain was created before or after a specific generation
+ * count (used for testing whether a node permission is older than a domain).
+ *
+ * Return values:
+ * -1: error
+ *  0: domain has higher generation count (it is younger than a node with the
+ *     given count), or domain isn't existing any longer
+ *  1: domain is older than the node
+ */
+static int chk_domain_generation(unsigned int domid, uint64_t gen)
+{
+	struct domain *d;
+	xc_dominfo_t dominfo;
+
+	if (!xc_handle && domid == 0)
+		return 1;
+
+	d = find_domain_struct(domid);
+	if (d)
+		return (d->generation <= gen) ? 1 : 0;
+
+	if (!get_domain_info(domid, &dominfo))
+		return 0;
+
+	d = alloc_domain(NULL, domid);
+	return d ? 1 : -1;
+}
+
+/*
+ * Remove permissions for no longer existing domains in order to avoid a new
+ * domain with the same domid inheriting the permissions.
+ */
+int domain_adjust_node_perms(struct node *node)
+{
+	unsigned int i;
+	int ret;
+
+	ret = chk_domain_generation(node->perms.p[0].id, node->generation);
+	if (ret < 0)
+		return errno;
+
+	/* If the owner doesn't exist any longer give it to priv domain. */
+	if (!ret)
+		node->perms.p[0].id = priv_domid;
+
+	for (i = 1; i < node->perms.num; i++) {
+		if (node->perms.p[i].perms & XS_PERM_IGNORE)
+			continue;
+		ret = chk_domain_generation(node->perms.p[i].id,
+					    node->generation);
+		if (ret < 0)
+			return errno;
+		if (!ret)
+			node->perms.p[i].perms |= XS_PERM_IGNORE;
+	}
+
+	return 0;
+}
+
 void domain_entry_dec(struct connection *conn, struct node *node)
 {
 	struct domain *d;
diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
index 259183962a..5e00087206 100644
--- a/tools/xenstore/xenstored_domain.h
+++ b/tools/xenstore/xenstored_domain.h
@@ -56,6 +56,9 @@ bool domain_can_write(struct connection *conn);
 
 bool domain_is_unprivileged(struct connection *conn);
 
+/* Remove node permissions for no longer existing domains. */
+int domain_adjust_node_perms(struct node *node);
+
 /* Quota manipulation */
 void domain_entry_inc(struct connection *conn, struct node *);
 void domain_entry_dec(struct connection *conn, struct node *);
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
index a7d8c5d475..2881f3b2e4 100644
--- a/tools/xenstore/xenstored_transaction.c
+++ b/tools/xenstore/xenstored_transaction.c
@@ -47,7 +47,12 @@
  * transaction.
  * Each time the global generation count is copied to either a node or a
  * transaction it is incremented. This ensures all nodes and/or transactions
- * are having a unique generation count.
+ * are having a unique generation count. The increment is done _before_ the
+ * copy as that is needed for checking whether a domain was created before
+ * or after a node has been written (the domain's generation is set with the
+ * actual generation count without incrementing it, in order to support
+ * writing a node for a domain before the domain has been officially
+ * introduced).
  *
  * Transaction conflicts are detected by checking the generation count of all
  * nodes read in the transaction to match with the generation count in the
@@ -161,7 +166,7 @@ struct transaction
 };
 
 extern int quota_max_transaction;
-static uint64_t generation;
+uint64_t generation;
 
 static void set_tdb_key(const char *name, TDB_DATA *key)
 {
@@ -237,7 +242,7 @@ int access_node(struct connection *conn, struct node *node,
 	bool introduce = false;
 
 	if (type != NODE_ACCESS_READ) {
-		node->generation = generation++;
+		node->generation = ++generation;
 		if (conn && !conn->transaction)
 			wrl_apply_debit_direct(conn);
 	}
@@ -374,7 +379,7 @@ static int finalize_transaction(struct connection *conn,
 				if (!data.dptr)
 					goto err;
 				hdr = (void *)data.dptr;
-				hdr->generation = generation++;
+				hdr->generation = ++generation;
 				ret = tdb_store(tdb_ctx, key, data,
 						TDB_REPLACE);
 				talloc_free(data.dptr);
@@ -462,7 +467,7 @@ int do_transaction_start(struct connection *conn, struct buffered_data *in)
 	INIT_LIST_HEAD(&trans->accessed);
 	INIT_LIST_HEAD(&trans->changed_domains);
 	trans->fail = false;
-	trans->generation = generation++;
+	trans->generation = ++generation;
 
 	/* Pick an unused transaction identifier. */
 	do {
diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
index 3386bac565..43a162bea3 100644
--- a/tools/xenstore/xenstored_transaction.h
+++ b/tools/xenstore/xenstored_transaction.h
@@ -27,6 +27,8 @@ enum node_access_type {
 
 struct transaction;
 
+extern uint64_t generation;
+
 int do_transaction_start(struct connection *conn, struct buffered_data *node);
 int do_transaction_end(struct connection *conn, struct buffered_data *in);
 
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 3e43f8809d..d407d5713a 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -152,7 +152,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
 bool xs_perm_to_string(const struct xs_permissions *perm,
                        char *buffer, size_t buf_len)
 {
-	switch ((int)perm->perms) {
+	switch ((int)perm->perms & ~XS_PERM_IGNORE) {
 	case XS_PERM_WRITE:
 		*buffer = 'w';
 		break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57227.100088 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61m-0006so-Te; Sun, 20 Dec 2020 21:14:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57227.100088; Sun, 20 Dec 2020 21:14:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61m-0006sg-Qi; Sun, 20 Dec 2020 21:14:06 +0000
Received: by outflank-mailman (input) for mailman id 57227;
 Sun, 20 Dec 2020 21:14:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61k-0006sS-Q2
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61k-0006UO-PL
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61k-0000pr-Of
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=6e2u/hx5alTORZjDWaUEL1qNgg/Ly7sQIjcc2huc/q0=; b=VN387ldiCQpwFTeSRNGzwZsgSN
	X6cWkMN8Y/hQFQXJH268t4AaU/9jbU2vZ+EVXZiCqUSciTcemGjHrsPm+HhFE65r+S3V/sbLO61tc
	FFf4DT9bNWbV+5B+fGS6bzxNvkYoG1y1CoR3swMEPsc99cioFk6bf31/h2tzAyB5vtVk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: clean up permissions for dead domains
Message-Id: <E1kr61k-0000pr-Of@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:04 +0000

commit 6aea4d88cdb3a403f373d270002d88d2881a94ae
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:20:30 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:20:30 2020 +0100

    tools/ocaml/xenstored: clean up permissions for dead domains
    
    domain ids are prone to wrapping (15-bits), and with sufficient number
    of VMs in a reboot loop it is possible to trigger it.  Xenstore entries
    may linger after a domain dies, until a toolstack cleans it up. During
    this time there is a window where a wrapped domid could access these
    xenstore keys (that belonged to another VM).
    
    To prevent this do a cleanup when a domain dies:
     * walk the entire xenstore tree and update permissions for all nodes
       * if the dead domain had an ACL entry: remove it
       * if the dead domain was the owner: change the owner to Dom0
    
    This is done without quota checks or a transaction. Quota checks would
    be a no-op (either the domain is dead, or it is Dom0 where they are not
    enforced).  Transactions are not needed, because this is all done
    atomically by oxenstored's single thread.
    
    The xenstore entries owned by the dead domain are not deleted, because
    that could confuse a toolstack / backends that are still bound to it
    (or generate unexpected watch events). It is the responsibility of a
    toolstack to remove the xenstore entries themselves.
    
    This is part of XSA-322.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/xenstored/perms.ml     |  9 +++++++++
 tools/ocaml/xenstored/process.ml   |  1 +
 tools/ocaml/xenstored/store.ml     | 16 ++++++++++++++++
 tools/ocaml/xenstored/xenstored.ml |  1 +
 4 files changed, 27 insertions(+)

diff --git a/tools/ocaml/xenstored/perms.ml b/tools/ocaml/xenstored/perms.ml
index ee7fee6bda..e8a16221f8 100644
--- a/tools/ocaml/xenstored/perms.ml
+++ b/tools/ocaml/xenstored/perms.ml
@@ -58,6 +58,15 @@ let get_other perms = perms.other
 let get_acl perms = perms.acl
 let get_owner perm = perm.owner
 
+(** [remote_domid ~domid perm] removes all ACLs for [domid] from perm.
+* If [domid] was the owner then it is changed to Dom0.
+* This is used for cleaning up after dead domains.
+* *)
+let remove_domid ~domid perm =
+	let acl = List.filter (fun (acl_domid, _) -> acl_domid <> domid) perm.acl in
+	let owner = if perm.owner = domid then 0 else perm.owner in
+	{ perm with acl; owner }
+
 let default0 = create 0 NONE []
 
 let perm_of_string s =
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index f99b9e935c..73e04cc18b 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -443,6 +443,7 @@ let do_release con t domains cons data =
 	let fire_spec_watches = Domains.exist domains domid in
 	Domains.del domains domid;
 	Connections.del_domain cons domid;
+	Store.reset_permissions (Transaction.get_store t) domid;
 	if fire_spec_watches
 	then Connections.fire_spec_watches (Transaction.get_root t) cons Store.Path.release_domain
 	else raise Invalid_Cmd_Args
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 52b88b3ee1..22d4ac159f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -89,6 +89,13 @@ let check_owner node connection =
 
 let rec recurse fct node = fct node; List.iter (recurse fct) node.children
 
+(** [recurse_map f tree] applies [f] on each node in the tree recursively *)
+let recurse_map f =
+	let rec walk node =
+		f { node with children = List.rev_map walk node.children |> List.rev }
+	in
+	walk
+
 let unpack node = (Symbol.to_string node.name, node.perms, node.value)
 
 end
@@ -435,6 +442,15 @@ let setperms store perm path nperms =
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
 
+let reset_permissions store domid =
+	Logging.info "store|node" "Cleaning up xenstore ACLs for domid %d" domid;
+	store.root <- Node.recurse_map (fun node ->
+		let perms = Perms.Node.remove_domid ~domid node.perms in
+		if perms <> node.perms then
+			Logging.debug "store|node" "Changed permissions for node %s" (Node.get_name node);
+		{ node with perms }
+	) store.root
+
 type ops = {
 	store: t;
 	write: Path.t -> string -> unit;
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 6926a4de41..a194cbc76f 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -340,6 +340,7 @@ let _ =
 			finally (fun () ->
 				if Some port = eventchn.Event.virq_port then (
 					let (notify, deaddom) = Domains.cleanup domains in
+					List.iter (Store.reset_permissions store) deaddom;
 					List.iter (Connections.del_domain cons) deaddom;
 					if deaddom <> [] || notify then
 						Connections.fire_spec_watches
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57228.100092 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61w-0006u5-VT; Sun, 20 Dec 2020 21:14:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57228.100092; Sun, 20 Dec 2020 21:14:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr61w-0006tx-SU; Sun, 20 Dec 2020 21:14:16 +0000
Received: by outflank-mailman (input) for mailman id 57228;
 Sun, 20 Dec 2020 21:14:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61u-0006tm-T8
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61u-0006UW-SM
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr61u-0000qg-RW
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8pbZmGzdR6XWoVFPAUtrvqKAIThQ8apD163Xd6TRu6c=; b=AOrQGA4Jfo+0Wto+Z9C77EXSY2
	dlar+wC9YOdDBF6byokS5vqtd6vgit48onVpWe3OsdJzCkamYwEo5qbSsDr9rdfaArO5D0pvO20+R
	CZYSAedry++rAgpJqmYUKvm92kUMwfhRyXrYNsBitywMpn1rQlLHJf3UpdSFu6uaByq8=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: Fix path length validation
Message-Id: <E1kr61u-0000qg-RW@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:14 +0000

commit 782aa4bb53145ebeadaf1dfa448d1dab144fa6d9
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:00 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:00 2020 +0100

    tools/ocaml/xenstored: Fix path length validation
    
    Currently, oxenstored checks the length of paths against 1024, then
    prepends "/local/domain/$DOMID/" to relative paths.  This allows a domU
    to create paths which can't subsequently be read by anyone, even dom0.
    This also interferes with listing directories, etc.
    
    Define a new oxenstored.conf entry: quota-path-max, defaulting to 1024
    as before.  For paths that begin with "/local/domain/$DOMID/" check the
    relative path length against this quota. For all other paths check the
    entire path length.
    
    This ensures that if the domid changes (and thus the length of a prefix
    changes) a path that used to be valid stays valid (e.g. after a
    live-migration).  It also ensures that regardless how the client tries
    to access a path (domid-relative or absolute) it will get consistent
    results, since the limit is always applied on the final canonicalized
    path.
    
    Delete the unused Domain.get_path to avoid it being confused with
    Connection.get_path (which differs by a trailing slash only).
    
    Rewrite Util.path_validate to apply the appropriate length restriction
    based on whether the path is relative or not.  Remove the check for
    connection_path being absolute, because it is not guest controlled data.
    
    This is part of XSA-323.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
---
 tools/ocaml/libs/xb/partial.ml           |  1 +
 tools/ocaml/libs/xb/partial.mli          |  1 +
 tools/ocaml/xenstored/define.ml          |  2 ++
 tools/ocaml/xenstored/domain.ml          |  1 -
 tools/ocaml/xenstored/oxenstored.conf.in |  1 +
 tools/ocaml/xenstored/utils.ml           | 15 ++++++++++++++-
 tools/ocaml/xenstored/xenstored.ml       |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index d4d1c7bdec..b6e2a716e2 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -28,6 +28,7 @@ external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
 let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+let xenstore_rel_path_max = 2048 (* xen/include/public/io/xs_wire.h *)
 
 let of_string s =
 	let tid, rid, opint, dlen = header_of_string_internal s in
diff --git a/tools/ocaml/libs/xb/partial.mli b/tools/ocaml/libs/xb/partial.mli
index 359a75e88d..b9216018f5 100644
--- a/tools/ocaml/libs/xb/partial.mli
+++ b/tools/ocaml/libs/xb/partial.mli
@@ -9,6 +9,7 @@ external header_size : unit -> int = "stub_header_size"
 external header_of_string_internal : string -> int * int * int * int
   = "stub_header_of_string"
 val xenstore_payload_max : int
+val xenstore_rel_path_max : int
 val of_string : string -> pkt
 val append : pkt -> string -> int -> unit
 val to_complete : pkt -> int
diff --git a/tools/ocaml/xenstored/define.ml b/tools/ocaml/xenstored/define.ml
index 2965c08534..f574397a4c 100644
--- a/tools/ocaml/xenstored/define.ml
+++ b/tools/ocaml/xenstored/define.ml
@@ -32,6 +32,8 @@ let conflict_rate_limit_is_aggregate = ref true
 
 let domid_self = 0x7FF0
 
+let path_max = ref Xenbus.Partial.xenstore_rel_path_max
+
 exception Not_a_directory of string
 exception Not_a_value of string
 exception Already_exist
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index aeb185ff7e..81cb59b8f1 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -38,7 +38,6 @@ type t =
 }
 
 let is_dom0 d = d.id = 0
-let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
 let get_id domain = domain.id
 let get_interface d = d.interface
 let get_mfn d = d.mfn
diff --git a/tools/ocaml/xenstored/oxenstored.conf.in b/tools/ocaml/xenstored/oxenstored.conf.in
index f843482981..4ae48e42d4 100644
--- a/tools/ocaml/xenstored/oxenstored.conf.in
+++ b/tools/ocaml/xenstored/oxenstored.conf.in
@@ -61,6 +61,7 @@ quota-maxsize = 2048
 quota-maxwatch = 100
 quota-transaction = 10
 quota-maxrequests = 1024
+quota-path-max = 1024
 
 # Activate filed base backend
 persistent = false
diff --git a/tools/ocaml/xenstored/utils.ml b/tools/ocaml/xenstored/utils.ml
index e8c9fe4e94..eb79bf0146 100644
--- a/tools/ocaml/xenstored/utils.ml
+++ b/tools/ocaml/xenstored/utils.ml
@@ -93,7 +93,7 @@ let read_file_single_integer filename =
 let path_validate path connection_path =
 	let len = String.length path in
 
-	if len = 0 || len > 1024 then raise Define.Invalid_path;
+	if len = 0 then raise Define.Invalid_path;
 
 	let abs_path =
 		match String.get path 0 with
@@ -101,4 +101,17 @@ let path_validate path connection_path =
 		| _   -> connection_path ^ path
 	in
 
+	(* Regardless whether client specified absolute or relative path,
+	   canonicalize it (above) and, for domain-relative paths, check the
+	   length of the relative part.
+
+	   This prevents paths becoming invalid across migrate when the length
+	   of the domid changes in @param connection_path.
+	 *)
+	let len = String.length abs_path in
+	let on_absolute _ _ = len in
+	let on_relative _ offset = len - offset in
+	let len = Scanf.ksscanf abs_path on_absolute "/local/domain/%d/%n" on_relative in
+	if len > !Define.path_max then raise Define.Invalid_path;
+
 	abs_path
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index a194cbc76f..369b5036f4 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -102,6 +102,7 @@ let parse_config filename =
 		("quota-maxentity", Config.Set_int Quota.maxent);
 		("quota-maxsize", Config.Set_int Quota.maxsize);
 		("quota-maxrequests", Config.Set_int Define.maxrequests);
+		("quota-path-max", Config.Set_int Define.path_max);
 		("test-eagain", Config.Set_bool Transaction.test_eagain);
 		("persistent", Config.Set_bool Disk.enable);
 		("xenstored-log-file", Config.String Logging.set_xenstored_log_destination);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57229.100096 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr627-0006vH-1B; Sun, 20 Dec 2020 21:14:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57229.100096; Sun, 20 Dec 2020 21:14:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr626-0006v9-UA; Sun, 20 Dec 2020 21:14:26 +0000
Received: by outflank-mailman (input) for mailman id 57229;
 Sun, 20 Dec 2020 21:14:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr624-0006uy-W4
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:24 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr624-0006Ui-VJ
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:24 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr624-0000rW-UT
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vGCTMyM4ESBmm2kamgOqH13dYJDQxjgA+aKDbqX+rCA=; b=VrCyCr6ZoaECiNSb8h9D08iiul
	ebmZWYHmUnYW7TYoYUmxiIupZbC3f2LLcte4h7I/UdJUXG4E4ULdCebdDoMeRlDsDTf/fZVKAmfqj
	/6+oUQxz0WILOFs9dq4w23J4LcfrlwkSplbDNHgejgepEGET849HbhlVSknbYtrptMoQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: drop watch event messages exceeding maximum size
Message-Id: <E1kr624-0000rW-UT@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:24 +0000

commit 18c0abb8f77be8ffbe5e02a6e9a4aec7c39a1d41
Author:     Juergen Gross <jgross@suse.com>
AuthorDate: Tue Dec 15 14:21:04 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:04 2020 +0100

    tools/xenstore: drop watch event messages exceeding maximum size
    
    By setting a watch with a very large tag it is possible to trick
    xenstored to send watch event messages exceeding the maximum allowed
    payload size. This might in turn lead to a crash of xenstored as the
    resulting error can cause dereferencing a NULL pointer in case there
    is no active request being handled by the guest the watch event is
    being sent to.
    
    Fix that by just dropping such watch events. Additionally modify the
    error handling to test the pointer to be not NULL before dereferencing
    it.
    
    This is XSA-324.
    
    Signed-off-by: Juergen Gross <jgross@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 tools/xenstore/xenstored_core.c  | 3 +++
 tools/xenstore/xenstored_watch.c | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index cb2c70bfe7..407e665755 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -680,6 +680,9 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 	/* Replies reuse the request buffer, events need a new one. */
 	if (type != XS_WATCH_EVENT) {
 		bdata = conn->in;
+		/* Drop asynchronous responses, e.g. errors for watch events. */
+		if (!bdata)
+			return;
 		bdata->inhdr = true;
 		bdata->used = 0;
 		conn->in = NULL;
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index 71c108ea99..9ff20690c0 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -92,6 +92,10 @@ static void add_event(struct connection *conn,
 	}
 
 	len = strlen(name) + 1 + strlen(watch->token) + 1;
+	/* Don't try to send over-long events. */
+	if (len > XENSTORE_PAYLOAD_MAX)
+		return;
+
 	data = talloc_array(ctx, char, len);
 	if (!data)
 		return;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57230.100100 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62G-0006wW-2j; Sun, 20 Dec 2020 21:14:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57230.100100; Sun, 20 Dec 2020 21:14:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62F-0006wN-Vp; Sun, 20 Dec 2020 21:14:35 +0000
Received: by outflank-mailman (input) for mailman id 57230;
 Sun, 20 Dec 2020 21:14:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62F-0006wG-2X
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62F-0006Us-1k
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62F-0000sN-18
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=SDcUCbYaKMuVG0zQDFLyijLaqUf+z1Ot3oJvtrmmcgY=; b=eASNmSZUUBzUVsJgJKluhM/jdk
	v5ooQrBw97u1JfFprFK9Sw3qA3whAeYs7fArdwHoOgRWhJRi1cyNOpYHu1hT/dmbG0s+6e0TmEpYv
	+/QcEwg0geEtB6z7PBA8AyWHFRpHn81rp3Vft2qGNXDVO26aKCXdO3qXw5J/qGnvs9dg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/xenstore: Preserve bad client until they are destroyed
Message-Id: <E1kr62F-0000sN-18@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:35 +0000

commit c6196caf012cd199d254526e2e8613385a0db7e4
Author:     Harsha Shamsundara Havanur <havanur@amazon.com>
AuthorDate: Tue Dec 15 14:21:09 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:09 2020 +0100

    tools/xenstore: Preserve bad client until they are destroyed
    
    XenStored will kill any connection that it thinks has misbehaved,
    this is currently happening in two places:
     * In `handle_input()` if the sanity check on the ring and the message
       fails.
     * In `handle_output()` when failing to write the response in the ring.
    
    As the domain structure is a child of the connection, XenStored will
    destroy its view of the domain when killing the connection. This will
    result in sending @releaseDomain event to all the watchers.
    
    As the watch event doesn't carry which domain has been released,
    the watcher (such as XenStored) will generally go through the list of
    domains registers and check if one of them is shutting down/dying.
    In the case of a client misbehaving, the domain will likely to be
    running, so no action will be performed.
    
    When the domain is effectively destroyed, XenStored will not be aware of
    the domain anymore. So the watch event is not going to be sent.
    By consequence, the watchers of the event will not release mappings
    they may have on the domain. This will result in a zombie domain.
    
    In order to send @releaseDomain event at the correct time, we want
    to keep the domain structure until the domain is effectively
    shutting-down/dying.
    
    We also want to keep the connection around so we could possibly revive
    the connection in the future.
    
    A new flag 'is_ignored' is added to mark whether a connection should be
    ignored when checking if there are work to do. Additionally any
    transactions, watches, buffers associated to the connection will be
    freed as you can't do much with them (restarting the connection will
    likely need a reset).
    
    As a side note, when the device model were running in a stubdomain, a
    guest would have been able to introduce a use-after-free because there
    is two parents for a guest connection.
    
    This is XSA-325.
    
    Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
    Signed-off-by: Harsha Shamsundara Havanur <havanur@amazon.com>
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Paul Durrant <paul@xen.org>
---
 tools/xenstore/xenstored_core.c   | 49 ++++++++++++++++++++++++++++++++-------
 tools/xenstore/xenstored_core.h   |  3 +++
 tools/xenstore/xenstored_domain.c |  8 +++++++
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 407e665755..08190ecc55 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1344,6 +1344,32 @@ static struct {
 	[XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
 
+/*
+ * Keep the connection alive but stop processing any new request or sending
+ * reponse. This is to allow sending @releaseDomain watch event at the correct
+ * moment and/or to allow the connection to restart (not yet implemented).
+ *
+ * All watches, transactions, buffers will be freed.
+ */
+static void ignore_connection(struct connection *conn)
+{
+	struct buffered_data *out, *tmp;
+
+	trace("CONN %p ignored\n", conn);
+
+	conn->is_ignored = true;
+	conn_delete_all_watches(conn);
+	conn_delete_all_transactions(conn);
+
+	list_for_each_entry_safe(out, tmp, &conn->out_list, list) {
+		list_del(&out->list);
+		talloc_free(out);
+	}
+
+	talloc_free(conn->in);
+	conn->in = NULL;
+}
+
 static const char *sockmsg_string(enum xsd_sockmsg_type type)
 {
 	if ((unsigned int)type < ARRAY_SIZE(wire_funcs) && wire_funcs[type].str)
@@ -1402,8 +1428,10 @@ static void consider_message(struct connection *conn)
 	assert(conn->in == NULL);
 }
 
-/* Errors in reading or allocating here mean we get out of sync, so we
- * drop the whole client connection. */
+/*
+ * Errors in reading or allocating here means we get out of sync, so we mark
+ * the connection as ignored.
+ */
 static void handle_input(struct connection *conn)
 {
 	int bytes;
@@ -1460,14 +1488,14 @@ static void handle_input(struct connection *conn)
 	return;
 
 bad_client:
-	/* Kill it. */
-	talloc_free(conn);
+	ignore_connection(conn);
 }
 
 static void handle_output(struct connection *conn)
 {
+	/* Ignore the connection if an error occured */
 	if (!write_messages(conn))
-		talloc_free(conn);
+		ignore_connection(conn);
 }
 
 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
@@ -1483,6 +1511,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read)
 	new->write = write;
 	new->read = read;
 	new->can_write = true;
+	new->is_ignored = false;
 	new->transaction_started = 0;
 	INIT_LIST_HEAD(&new->out_list);
 	INIT_LIST_HEAD(&new->watches);
@@ -2185,8 +2214,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLIN)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLIN) &&
+						 !conn->is_ignored)
 						handle_input(conn);
 				}
 				if (talloc_free(conn) == 0)
@@ -2198,8 +2228,9 @@ int main(int argc, char *argv[])
 					if (fds[conn->pollfd_idx].revents
 					    & ~(POLLIN|POLLOUT))
 						talloc_free(conn);
-					else if (fds[conn->pollfd_idx].revents
-						 & POLLOUT)
+					else if ((fds[conn->pollfd_idx].revents
+						  & POLLOUT) &&
+						 !conn->is_ignored)
 						handle_output(conn);
 				}
 				if (talloc_free(conn) == 0)
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index eb19b71f5f..196a6fd2b0 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -80,6 +80,9 @@ struct connection
 	/* Is this a read-only connection? */
 	bool can_write;
 
+	/* Is this connection ignored? */
+	bool is_ignored;
+
 	/* Buffered incoming data. */
 	struct buffered_data *in;
 
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 2a02b22933..cbd8e6b747 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -290,6 +290,10 @@ bool domain_can_read(struct connection *conn)
 
 	if (domain_is_unprivileged(conn) && conn->domain->wrl_credit < 0)
 		return false;
+
+	if (conn->is_ignored)
+		return false;
+
 	return (intf->req_cons != intf->req_prod);
 }
 
@@ -307,6 +311,10 @@ bool domain_is_unprivileged(struct connection *conn)
 bool domain_can_write(struct connection *conn)
 {
 	struct xenstore_domain_interface *intf = conn->domain->interface;
+
+	if (conn->is_ignored)
+		return false;
+
 	return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57231.100104 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62Q-0006xu-46; Sun, 20 Dec 2020 21:14:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57231.100104; Sun, 20 Dec 2020 21:14:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62Q-0006xm-1A; Sun, 20 Dec 2020 21:14:46 +0000
Received: by outflank-mailman (input) for mailman id 57231;
 Sun, 20 Dec 2020 21:14:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62P-0006xd-5s
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62P-0006V5-4M
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62P-0000tF-3k
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=JkUCmGH28xIrAvyrav5ly2YEPdwcN1XVu1WA7WorBC0=; b=PaFQtvq6sga2OfrGbBEEKAWp4f
	NG4hhiIrjBVbxRsrfGqd147fdTZqFWDp6IJ60Fezp5JiaUl8yyjwhrzVBkYoSzJUyWZzOQyYW2TfF
	20ELuyTi5airI5aO9hEKIdhnN1w5su8P3S15JUROhaRqzCUjxk8qAXHB5EvFgU1LcZ9A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: delete watch from trie too when resetting watches
Message-Id: <E1kr62P-0000tF-3k@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:45 +0000

commit d6a55f1c676ee4b0b43dfa5c2365383c017ae791
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:23 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:23 2020 +0100

    tools/ocaml/xenstored: delete watch from trie too when resetting watches
    
    c/s f8c72b526129 "oxenstored: implement XS_RESET_WATCHES" from Xen 4.6
    introduced reset watches support in oxenstored by mirroring the change
    in cxenstored.
    
    However the OCaml version has some additional data structures to
    optimize watch firing, and just resetting the watches in one of the data
    structures creates a security bug where a malicious guest kernel can
    exceed its watch quota, driving oxenstored into OOM:
     * create watches
     * reset watches (this still keeps the watches lingering in another data
       structure, using memory)
     * create some more watches
     * loop until oxenstored dies
    
    The guest kernel doesn't necessarily have to be malicious to trigger
    this:
     * if control/platform-feature-xs_reset_watches is set
     * the guest kexecs (e.g. because it crashes)
     * on boot more watches are set up
     * this will slowly "leak" memory for watches in oxenstored, driving it
       towards OOM.
    
    This is XSA-330.
    
    Fixes: f8c72b526129 ("oxenstored: implement XS_RESET_WATCHES")
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/connections.ml | 4 ++++
 tools/ocaml/xenstored/process.ml     | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/ocaml/xenstored/connections.ml b/tools/ocaml/xenstored/connections.ml
index 834955fb08..1a70d412d5 100644
--- a/tools/ocaml/xenstored/connections.ml
+++ b/tools/ocaml/xenstored/connections.ml
@@ -134,6 +134,10 @@ let del_watch cons con path token =
 		cons.watches <- Trie.set cons.watches key watches;
  	watch
 
+let del_watches cons con =
+	Connection.del_watches con;
+	cons.watches <- Trie.map (del_watches_of_con con) cons.watches
+
 (* path is absolute *)
 let fire_watches ?oldroot root cons path recurse =
 	let key = key_of_path path in
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 73e04cc18b..437d2dcf9e 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -179,8 +179,8 @@ let do_isintroduced con _t domains _cons data =
 	if domid = Define.domid_self || Domains.exist domains domid then "T\000" else "F\000"
 
 (* only in xen >= 4.2 *)
-let do_reset_watches con _t _domains _cons _data =
-  Connection.del_watches con;
+let do_reset_watches con _t _domains cons _data =
+  Connections.del_watches cons con;
   Connection.del_transactions con
 
 (* only in >= xen3.3                                                                                    *)
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:14:56 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:14:56 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57232.100108 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62a-0006zh-6v; Sun, 20 Dec 2020 21:14:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57232.100108; Sun, 20 Dec 2020 21:14:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62a-0006zZ-42; Sun, 20 Dec 2020 21:14:56 +0000
Received: by outflank-mailman (input) for mailman id 57232;
 Sun, 20 Dec 2020 21:14:55 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62Z-0006zP-7d
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:55 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62Z-0006VV-6v
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:55 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62Z-0000uD-6I
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:14:55 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=BM/PLMRuLKEZ3h+u6KiI16Qaizilz21twaQ0yePzS/U=; b=RXb0eL3EH8cNt0auFnohrAr9Nt
	xKrBKNEO/U83dGzHXIqp186GtPFyTqmnMa4FZ5zMDmi3iwwcVA4RPGrA5++tng5Ue6Do2jT+YN5I9
	wLpezApoN3swu3TQVoYmCfJcW9hBBh+hO2HC3wzqF08cihQs+lAwBfUxbE4YVVyL5zaU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] tools/ocaml/xenstored: only Dom0 can change node owner
Message-Id: <E1kr62Z-0000uD-6I@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:14:55 +0000

commit a2f7ae132da97de094754a2122a8f23567b610e0
Author:     Edwin Török <edvin.torok@citrix.com>
AuthorDate: Tue Dec 15 14:21:28 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:21:28 2020 +0100

    tools/ocaml/xenstored: only Dom0 can change node owner
    
    Otherwise we can give quota away to another domain, either causing it to run
    out of quota, or in case of Dom0 use unbounded amounts of memory and bypass
    the quota system entirely.
    
    This was fixed in the C version of xenstored in 2006 (c/s db34d2aaa5f5,
    predating the XSA process by 5 years).
    
    It was also fixed in the mirage version of xenstore in 2012, with a unit test
    demonstrating the vulnerability:
    
      https://github.com/mirage/ocaml-xenstore/commit/6b91f3ac46b885d0530a51d57a9b3a57d64923a7
      https://github.com/mirage/ocaml-xenstore/commit/22ee5417c90b8fda905c38de0d534506152eace6
    
    but possibly without realising that the vulnerability still affected the
    in-tree oxenstored (added c/s f44af660412 in 2010).
    
    This is XSA-352.
    
    Signed-off-by: Edwin Török <edvin.torok@citrix.com>
    Acked-by: Christian Lindig <christian.lindig@citrix.com>
    Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/ocaml/xenstored/store.ml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 22d4ac159f..e20767372f 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -437,7 +437,8 @@ let setperms store perm path nperms =
 	| Some node ->
 		let old_owner = Node.get_owner node in
 		let new_owner = Perms.Node.get_owner nperms in
-		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then Quota.check store.quota new_owner 0;
+		if not ((old_owner = new_owner) || (Perms.Connection.is_dom0 perm)) then
+			raise Define.Permission_denied;
 		store.root <- path_setperms store perm path nperms;
 		Quota.del_entry store.quota old_owner;
 		Quota.add_entry store.quota new_owner
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:15:06 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:15:06 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57233.100112 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62k-00070y-91; Sun, 20 Dec 2020 21:15:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57233.100112; Sun, 20 Dec 2020 21:15:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62k-00070p-5Z; Sun, 20 Dec 2020 21:15:06 +0000
Received: by outflank-mailman (input) for mailman id 57233;
 Sun, 20 Dec 2020 21:15:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62j-00070h-Am
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62j-0006W5-A4
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62j-0000x2-9S
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=70gh6ukZpTAGfmnfecOfZ8XbAFdVgRMDrhZjpzS3dgQ=; b=i3y4zS4AfXF9kby3xiT7/5PdXK
	Vb9x0dz7ULbCoFtpgY29Q/HDuDFlVRUp5M6e5vMdYxBHqkuoWNnaRcGYmUEYUyGixwxcdijOMKewh
	MxK6rpEgEN08/Noul+60SNvJFSTiVBs71xziToMVpNjBNYyxmOdI5/awFtPg1GcUkpY0=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86: replace reset_stack_and_jump_nolp()
Message-Id: <E1kr62j-0000x2-9S@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:15:05 +0000

commit d39eb6fbb3ef0ef72f2fa88c9710e1416bc3a878
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:22:22 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:22:22 2020 +0100

    x86: replace reset_stack_and_jump_nolp()
    
    Move the necessary check into check_for_livepatch_work(), rather than
    mostly duplicating reset_stack_and_jump() for this purpose. This is to
    prevent an inflation of reset_stack_and_jump() flavors.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e3df3fbc448b9ae401332ba7d71c190d2efe3ae8
    master date: 2020-12-15 13:40:27 +0100
---
 xen/arch/x86/domain.c         |  2 +-
 xen/arch/x86/hvm/svm/svm.c    |  2 +-
 xen/arch/x86/hvm/vmx/vmcs.c   |  2 +-
 xen/arch/x86/pv/domain.c      |  2 +-
 xen/arch/x86/setup.c          |  2 +-
 xen/common/livepatch.c        |  5 +++++
 xen/include/asm-x86/current.h | 10 ++--------
 7 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 135c6d5b82..f4f55d0d84 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -192,7 +192,7 @@ static void noreturn continue_idle_domain(struct vcpu *v)
 {
     /* Idle vcpus might be attached to non-idle units! */
     if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump_nolp(guest_idle_loop);
+        reset_stack_and_jump(guest_idle_loop);
 
     reset_stack_and_jump(idle_loop);
 }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index fb73319cae..1f7b26151b 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1032,7 +1032,7 @@ static void noreturn svm_do_resume(struct vcpu *v)
 
     hvm_do_resume(v);
 
-    reset_stack_and_jump_nolp(svm_asm_do_resume);
+    reset_stack_and_jump(svm_asm_do_resume);
 }
 
 void svm_vmenter_helper(const struct cpu_user_regs *regs)
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index d53eceb23a..f10f6b78ec 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1889,7 +1889,7 @@ void vmx_do_resume(struct vcpu *v)
     if ( host_cr4 != read_cr4() )
         __vmwrite(HOST_CR4, read_cr4());
 
-    reset_stack_and_jump_nolp(vmx_asm_do_vmentry);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 static inline unsigned long vmr(unsigned long field)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index aea8d6b2b9..efaa2e7abf 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -61,7 +61,7 @@ custom_runtime_param("pcid", parse_pcid);
 static void noreturn continue_nonidle_domain(struct vcpu *v)
 {
     check_wakeup_from_wait();
-    reset_stack_and_jump_nolp(ret_from_intr);
+    reset_stack_and_jump(ret_from_intr);
 }
 
 static int setup_compat_l4(struct vcpu *v)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index ae61e93024..cc7274eae6 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -631,7 +631,7 @@ static void __init noreturn reinit_bsp_stack(void)
     stack_base[0] = stack;
     memguard_guard_stack(stack);
 
-    reset_stack_and_jump_nolp(init_done);
+    reset_stack_and_jump(init_done);
 }
 
 /*
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 1f89984c9a..bace2da70c 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -1300,6 +1300,11 @@ void check_for_livepatch_work(void)
     s_time_t timeout;
     unsigned long flags;
 
+    /* Only do any work when invoked in truly idle state. */
+    if ( system_state != SYS_STATE_active ||
+         !is_idle_domain(current->sched_unit->domain) )
+        return;
+
     /* Fast path: no work to do. */
     if ( !per_cpu(work_to_do, cpu ) )
         return;
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 0b47485337..d930b79404 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -129,22 +129,16 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define switch_stack_and_jump(fn, instr)                                \
+#define reset_stack_and_jump(fn)                                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
-            instr                                                       \
+            CHECK_FOR_LIVEPATCH_WORK                                    \
              "jmp %c1"                                                  \
             : : "r" (guest_cpu_user_regs()), "i" (fn) : "memory" );     \
         unreachable();                                                  \
     })
 
-#define reset_stack_and_jump(fn)                                        \
-    switch_stack_and_jump(fn, CHECK_FOR_LIVEPATCH_WORK)
-
-#define reset_stack_and_jump_nolp(fn)                                   \
-    switch_stack_and_jump(fn, "")
-
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:15:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:15:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57234.100117 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62u-00072B-Ai; Sun, 20 Dec 2020 21:15:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57234.100117; Sun, 20 Dec 2020 21:15:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr62u-000720-7F; Sun, 20 Dec 2020 21:15:16 +0000
Received: by outflank-mailman (input) for mailman id 57234;
 Sun, 20 Dec 2020 21:15:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62t-00071s-DY
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62t-0006WD-Ct
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr62t-0000y1-C5
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=gQ0jmZ9it5XuRaOKmRxvW3yiJsRCRY6TBec4tTQS/RM=; b=Swz8FRa6MwMu1XzH9PBo5SOVpe
	aaZM5KjRcoFQuVWkav9S4MrsXaXlD0rkKYtdH1U/n1byuiH/oNaFx4qSuEsLefBRAgDSATKWb9SVj
	8VkDuSkQeAzBa+0hWSogiZInmne+HAcLBN7L57OiY8SUjO6D4U8oInOk3yyiPBhB+rp4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86: fold guest_idle_loop() into idle_loop()
Message-Id: <E1kr62t-0000y1-C5@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:15:15 +0000

commit 13afcdf6f4c71d72c3d1fb31c24192ba8169f52e
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:23:05 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:23:05 2020 +0100

    x86: fold guest_idle_loop() into idle_loop()
    
    The latter can easily be made cover both cases. This is in preparation
    of using idle_loop directly for populating idle_csw.tail.
    
    Take the liberty and also adjust indentation / spacing in involved code.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: 058e469ab4d5cc5959423aafd6ba181dfc310a7f
    master date: 2020-12-15 13:41:09 +0100
---
 xen/arch/x86/domain.c | 44 +++++++++++++++++---------------------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index f4f55d0d84..406f889880 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -133,14 +133,22 @@ void play_dead(void)
 static void idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
+    /*
+     * Idle vcpus might be attached to non-idle units! We don't do any
+     * standard idle work like tasklets or livepatching in this case.
+     */
+    bool guest = !is_idle_domain(current->sched_unit->domain);
 
     for ( ; ; )
     {
         if ( cpu_is_offline(cpu) )
+        {
+            ASSERT(!guest);
             play_dead();
+        }
 
         /* Are we here for running vcpu context tasklets, or for idling? */
-        if ( unlikely(tasklet_work_to_do(cpu)) )
+        if ( !guest && unlikely(tasklet_work_to_do(cpu)) )
         {
             do_tasklet();
             /* Livepatch work is always kicked off via a tasklet. */
@@ -151,28 +159,14 @@ static void idle_loop(void)
          * and then, after it is done, whether softirqs became pending
          * while we were scrubbing.
          */
-        else if ( !softirq_pending(cpu) && !scrub_free_pages()  &&
-                    !softirq_pending(cpu) )
-            pm_idle();
-        do_softirq();
-    }
-}
-
-/*
- * Idle loop for siblings in active schedule units.
- * We don't do any standard idle work like tasklets or livepatching.
- */
-static void guest_idle_loop(void)
-{
-    unsigned int cpu = smp_processor_id();
-
-    for ( ; ; )
-    {
-        ASSERT(!cpu_is_offline(cpu));
-
-        if ( !softirq_pending(cpu) && !scrub_free_pages() &&
-             !softirq_pending(cpu))
-            sched_guest_idle(pm_idle, cpu);
+        else if ( !softirq_pending(cpu) && !scrub_free_pages() &&
+                  !softirq_pending(cpu) )
+        {
+            if ( guest )
+                sched_guest_idle(pm_idle, cpu);
+            else
+                pm_idle();
+        }
         do_softirq();
     }
 }
@@ -190,10 +184,6 @@ void startup_cpu_idle_loop(void)
 
 static void noreturn continue_idle_domain(struct vcpu *v)
 {
-    /* Idle vcpus might be attached to non-idle units! */
-    if ( !is_idle_domain(v->sched_unit->domain) )
-        reset_stack_and_jump(guest_idle_loop);
-
     reset_stack_and_jump(idle_loop);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:15:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:15:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57235.100120 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr634-00073V-Bx; Sun, 20 Dec 2020 21:15:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57235.100120; Sun, 20 Dec 2020 21:15:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr634-00073N-8r; Sun, 20 Dec 2020 21:15:26 +0000
Received: by outflank-mailman (input) for mailman id 57235;
 Sun, 20 Dec 2020 21:15:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr633-00073F-Gi
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr633-0006WJ-G2
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr633-0000yy-FN
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=YTaHdRas2IITUzHYtLkqzsE1e01QA6ZyAsNnci+qqfU=; b=gmRdU97bWTclgpHvWSHXNWTdkT
	L7/r7TrPlMaSlAgts7Vv9zmcQ4v7HNiT0Hfv844lBywhgjm8vxuK10sQvkAKuEC7ebIgs2oDy84Q9
	SZSsegaDLjR88szNFxKlBeGawkKe1F2s7l5lXD2IGOJP9Co40bAyIWV6l2Z/nR3uNUUk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] x86: avoid calling {svm,vmx}_do_resume()
Message-Id: <E1kr633-0000yy-FN@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:15:25 +0000

commit 16d0dc0edaac18d7e269324b183ddccdcf8a5e94
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:23:33 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:23:33 2020 +0100

    x86: avoid calling {svm,vmx}_do_resume()
    
    These functions follow the following path: hvm_do_resume() ->
    handle_hvm_io_completion() -> hvm_wait_for_io() ->
    wait_on_xen_event_channel() -> do_softirq() -> schedule() ->
    sched_context_switch() -> continue_running() and hence may
    recursively invoke themselves. If this ends up happening a couple of
    times, a stack overflow would result.
    
    Prevent this by also resetting the stack at the
    ->arch.ctxt_switch->tail() invocations (in both places for consistency)
    and thus jumping to the functions instead of calling them.
    
    This is XSA-348 / CVE-2020-29566.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    master commit: e6ebd394385db52855d1517cea829ffff68b34b8
    master date: 2020-12-15 13:41:23 +0100
---
 xen/arch/x86/domain.c             | 21 ++++-----------------
 xen/arch/x86/hvm/svm/svm.c        |  3 ++-
 xen/arch/x86/hvm/vmx/vmcs.c       |  3 ++-
 xen/arch/x86/pv/domain.c          |  2 +-
 xen/include/asm-x86/current.h     | 13 ++++++++++---
 xen/include/asm-x86/domain.h      |  2 +-
 xen/include/asm-x86/hvm/vmx/vmx.h |  2 +-
 7 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 406f889880..820cb0f905 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -130,7 +130,7 @@ void play_dead(void)
         dead_idle();
 }
 
-static void idle_loop(void)
+static void noreturn idle_loop(void)
 {
     unsigned int cpu = smp_processor_id();
     /*
@@ -182,11 +182,6 @@ void startup_cpu_idle_loop(void)
     reset_stack_and_jump(idle_loop);
 }
 
-static void noreturn continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
 void init_hypercall_page(struct domain *d, void *ptr)
 {
     memset(ptr, 0xcc, PAGE_SIZE);
@@ -535,7 +530,7 @@ int arch_domain_create(struct domain *d,
         static const struct arch_csw idle_csw = {
             .from = paravirt_ctxt_switch_from,
             .to   = paravirt_ctxt_switch_to,
-            .tail = continue_idle_domain,
+            .tail = idle_loop,
         };
 
         d->arch.ctxt_switch = &idle_csw;
@@ -1833,20 +1828,12 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
     /* Ensure that the vcpu has an up-to-date time base. */
     update_vcpu_system_time(next);
 
-    /*
-     * Schedule tail *should* be a terminal function pointer, but leave a
-     * bug frame around just in case it returns, to save going back into the
-     * context switching code and leaving a far more subtle crash to diagnose.
-     */
-    nextd->arch.ctxt_switch->tail(next);
-    BUG();
+    reset_stack_and_jump_ind(nextd->arch.ctxt_switch->tail);
 }
 
 void continue_running(struct vcpu *same)
 {
-    /* See the comment above. */
-    same->domain->arch.ctxt_switch->tail(same);
-    BUG();
+    reset_stack_and_jump_ind(same->domain->arch.ctxt_switch->tail);
 }
 
 int __sync_local_execstate(void)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 1f7b26151b..a6de9ccb8f 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -987,8 +987,9 @@ static void svm_ctxt_switch_to(struct vcpu *v)
         wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
 }
 
-static void noreturn svm_do_resume(struct vcpu *v)
+static void noreturn svm_do_resume(void)
 {
+    struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
     bool debug_state = (v->domain->debugger_attached ||
                         v->domain->arch.monitor.software_breakpoint_enabled ||
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index f10f6b78ec..f3bd7f9bee 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1830,8 +1830,9 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
-void vmx_do_resume(struct vcpu *v)
+void vmx_do_resume(void)
 {
+    struct vcpu *v = current;
     bool_t debug_state;
     unsigned long host_cr4;
 
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index efaa2e7abf..f2d66b479e 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -58,7 +58,7 @@ static int parse_pcid(const char *s)
 }
 custom_runtime_param("pcid", parse_pcid);
 
-static void noreturn continue_nonidle_domain(struct vcpu *v)
+static void noreturn continue_nonidle_domain(void)
 {
     check_wakeup_from_wait();
     reset_stack_and_jump(ret_from_intr);
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index d930b79404..a11d15cecb 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -129,16 +129,23 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define CHECK_FOR_LIVEPATCH_WORK ""
 #endif
 
-#define reset_stack_and_jump(fn)                                        \
+#define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         __asm__ __volatile__ (                                          \
             "mov %0,%%"__OP"sp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
-             "jmp %c1"                                                  \
-            : : "r" (guest_cpu_user_regs()), "i" (fn) : "memory" );     \
+            instr "1"                                                   \
+            : : "r" (guest_cpu_user_regs()), constr (fn) : "memory" );  \
         unreachable();                                                  \
     })
 
+#define reset_stack_and_jump(fn)                                        \
+    switch_stack_and_jump(fn, "jmp %c", "i")
+
+/* The constraint may only specify non-call-clobbered registers. */
+#define reset_stack_and_jump_ind(fn)                                    \
+    switch_stack_and_jump(fn, "INDIRECT_JMP %", "b")
+
 /*
  * Which VCPU's state is currently running on each CPU?
  * This is not necesasrily the same as 'current' as a CPU may be
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 1cd8743d11..309b56e2d6 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -313,7 +313,7 @@ struct arch_domain
     const struct arch_csw {
         void (*from)(struct vcpu *);
         void (*to)(struct vcpu *);
-        void (*tail)(struct vcpu *);
+        void noreturn (*tail)(void);
     } *ctxt_switch;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 371b912887..591c598030 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -95,7 +95,7 @@ typedef enum {
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
 void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
-void noreturn vmx_do_resume(struct vcpu *);
+void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
 void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
 void vmx_realmode(struct cpu_user_regs *regs);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:15:36 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:15:36 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57236.100123 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr63E-00074j-Dp; Sun, 20 Dec 2020 21:15:36 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57236.100123; Sun, 20 Dec 2020 21:15:36 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr63E-00074b-AZ; Sun, 20 Dec 2020 21:15:36 +0000
Received: by outflank-mailman (input) for mailman id 57236;
 Sun, 20 Dec 2020 21:15:35 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63D-00074V-JS
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:35 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63D-0006WR-In
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:35 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63D-000106-I3
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:35 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=tveU+nq+7uSMcvfslml3Vh/+BdV4N2RgCc3ilsqhVgs=; b=BATY/y4/yTU4M1Ed3k3akFuGR1
	wMY148jR6ZyvkOTpSVWM9U75SKRKj5PDUxfpqCA71TWtjlUR6Es6QsTI8IAlQ7vrB4k3/FjblipV7
	StIY1NWx/Ceub98muK1qVwAnZjqJ9DXcfn+QuPX/b1luD2+JM3G8YvJtg81BusTbLjsw=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] evtchn/FIFO: re-order and synchronize (with) map_control_block()
Message-Id: <E1kr63D-000106-I3@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:15:35 +0000

commit bb534d6515080770178b6b750d1cb96968debbc6
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:24:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:24:19 2020 +0100

    evtchn/FIFO: re-order and synchronize (with) map_control_block()
    
    For evtchn_fifo_set_pending()'s check of the control block having been
    set to be effective, ordering of respective reads and writes needs to be
    ensured: The control block pointer needs to be recorded strictly after
    the setting of all the queue heads, and it needs checking strictly
    before any uses of them (this latter aspect was already guaranteed).
    
    This is XSA-358 / CVE-2020-29570.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Julien Grall <jgrall@amazon.com>
    master commit: c5e63651fdc706954d920a2d98f74f4a21b46a7e
    master date: 2020-12-15 13:46:37 +0100
---
 xen/common/event_fifo.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 2f5e868b7a..742ca31449 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -228,6 +228,10 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
             goto unlock;
         }
 
+        /*
+         * This also acts as the read counterpart of the smp_wmb() in
+         * map_control_block().
+         */
         if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
             goto unlock;
 
@@ -453,6 +457,7 @@ static int setup_control_block(struct vcpu *v)
 static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
 {
     void *virt;
+    struct evtchn_fifo_control_block *control_block;
     unsigned int i;
     int rc;
 
@@ -463,10 +468,15 @@ static int map_control_block(struct vcpu *v, uint64_t gfn, uint32_t offset)
     if ( rc < 0 )
         return rc;
 
-    v->evtchn_fifo->control_block = virt + offset;
+    control_block = virt + offset;
 
     for ( i = 0; i <= EVTCHN_FIFO_PRIORITY_MIN; i++ )
-        v->evtchn_fifo->queue[i].head = &v->evtchn_fifo->control_block->head[i];
+        v->evtchn_fifo->queue[i].head = &control_block->head[i];
+
+    /* All queue heads must have been set before setting the control block. */
+    smp_wmb();
+
+    v->evtchn_fifo->control_block = control_block;
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Sun Dec 20 21:15:46 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Sun, 20 Dec 2020 21:15:46 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57237.100128 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr63O-00076T-HD; Sun, 20 Dec 2020 21:15:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57237.100128; Sun, 20 Dec 2020 21:15:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kr63O-00076L-EM; Sun, 20 Dec 2020 21:15:46 +0000
Received: by outflank-mailman (input) for mailman id 57237;
 Sun, 20 Dec 2020 21:15:45 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63N-00076D-MB
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:45 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63N-0006We-LW
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:45 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kr63N-00011D-Ko
 for xen-changelog@lists.xenproject.org; Sun, 20 Dec 2020 21:15:45 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=9+vZRGdjBmdUKLsN19yCMwm44oD+nCPqbIxB1uthLkM=; b=OrdSEPXwfgeNmH8BY8dV1MuZ97
	j9Y6WMy+Zr3WRotD1hyn/wnaN+eXIj+TUuKsgUqtEUcw0KQpWbqbZe0Tp6cIUyAVETSH9icPACL/G
	FBnIOa8K+kk91m4oL8lAmQt1S5VTWvdxJ8Dh8iveuFhAs+CWEDA16BcOLeeNDhNtbeWU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen stable-4.13] evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
Message-Id: <E1kr63N-00011D-Ko@xenbits.xenproject.org>
Date: Sun, 20 Dec 2020 21:15:45 +0000

commit 10c7c213bef26274684798deb3e351a6756046d2
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 15 14:24:48 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 15 14:24:48 2020 +0100

    evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
    
    Besides with add_page_to_event_array() the function also needs to
    synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
    and (subsequently) d->evtchn_port_ops.
    
    This is XSA-359 / CVE-2020-29571.
    
    Reported-by: Julien Grall <jgrall@amazon.com>
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Julien Grall <jgrall@amazon.com>
    master commit: dc8b01affd7f6f36d34c3854f51df0847df3ec0e
    master date: 2020-12-15 13:42:51 +0100
---
 xen/common/event_fifo.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index 742ca31449..afbc8d21da 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -597,6 +604,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13


From xen-changelog-bounces@lists.xenproject.org Mon Dec 21 14:22:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 21 Dec 2020 14:22:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57394.100391 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krM4c-0003uQ-5L; Mon, 21 Dec 2020 14:22:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57394.100391; Mon, 21 Dec 2020 14:22:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krM4c-0003uH-1x; Mon, 21 Dec 2020 14:22:06 +0000
Received: by outflank-mailman (input) for mailman id 57394;
 Mon, 21 Dec 2020 14:22:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4a-0003uA-UG
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4a-0006tL-Rv
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4a-0007qH-QQ
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=VrE6fFVYTSmtTmFuXm0u0EUSlQqDNBn1VeMH85XxWCU=; b=nqntUQeyL3rv+YLCTd1HMJ81MO
	WEsOJzeMXCq5x3afDl1BJ/4EV+pHghIwVTEMRZvVSKZmZRcvYa8EZkXhqPXN3653E+qHGePkJ8Fd7
	AHOch8VwLRcpfcnpktTUBNVPmzP8Pyb3vA2Mt9OF8CNqqLhl3CUztDU5D5AYkzTkwx9A=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/Kconfig: Correct the NR_CPUS description
Message-Id: <E1krM4a-0007qH-QQ@xenbits.xenproject.org>
Date: Mon, 21 Dec 2020 14:22:04 +0000

commit 6131dab5f2c8059a0fc7fd884bc6d4ff78ba44c2
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Fri Dec 18 23:30:04 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 14:11:25 2020 +0000

    xen/Kconfig: Correct the NR_CPUS description
    
    The description "physical CPUs" is especially wrong, as it implies the number
    of sockets, which tops out at 8 on all but the very biggest servers.
    
    NR_CPUS is the number of logical entities the scheduler can use.
    
    Reported-by: hanetzer@startmail.com
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/Kconfig | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/arch/Kconfig b/xen/arch/Kconfig
index 1954d1c5c1..d144d4c8d3 100644
--- a/xen/arch/Kconfig
+++ b/xen/arch/Kconfig
@@ -1,11 +1,17 @@
 
 config NR_CPUS
-	int "Maximum number of physical CPUs"
+	int "Maximum number of CPUs"
 	range 1 4095
 	default "256" if X86
 	default "8" if ARM && RCAR3
 	default "4" if ARM && QEMU
 	default "4" if ARM && MPSOC
 	default "128" if ARM
-	---help---
-	  Specifies the maximum number of physical CPUs which Xen will support.
+	help
+	  Controls the build-time size of various arrays and bitmaps
+	  associated with multiple-cpu management.  It is the upper bound of
+	  the number of logical entities the scheduler can run code on.
+
+	  For CPU cores which support Simultaneous Multi-Threading or similar
+	  technologies, this the number of logical threads which Xen will
+	  support.
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 21 14:22:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 21 Dec 2020 14:22:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57395.100394 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krM4m-0003v5-6k; Mon, 21 Dec 2020 14:22:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57395.100394; Mon, 21 Dec 2020 14:22:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krM4m-0003ux-3c; Mon, 21 Dec 2020 14:22:16 +0000
Received: by outflank-mailman (input) for mailman id 57395;
 Mon, 21 Dec 2020 14:22:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4l-0003uo-1Y
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4l-0006tO-0O
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krM4k-0007r0-US
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 14:22:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=eHu1fWHOJGP6zCDstac4PUF58D+dL/gHRAl8dHWYcjs=; b=2axDYQkoiDg6kpgYplaQ/7w/EK
	oSNdKjHuoI7GY0nBvzJg2livxuCHXGKTcdMDt4bZ7vgFdrOCY/t9NGXRd60xmLIPF9RYDCV5sDKvI
	lFFGif5VXUaaWDpobPrK11OQ5CRwvEl4Oe8TH4XUInbxXqNNlzaOZ6K5SXOhON/LJIXY=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/x86: Fix memory leak in vcpu_create() error path
Message-Id: <E1krM4k-0007r0-US@xenbits.xenproject.org>
Date: Mon, 21 Dec 2020 14:22:14 +0000

commit d162f36848c4a98a782cc05820b0aa7ec1ae297d
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 15:25:44 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 14:11:25 2020 +0000

    xen/x86: Fix memory leak in vcpu_create() error path
    
    Various paths in vcpu_create() end up calling paging_update_paging_modes(),
    which eventually allocate a monitor pagetable if one doesn't exist.
    
    However, an error in vcpu_create() results in the vcpu being cleaned up
    locally, and not put onto the domain's vcpu list.  Therefore, the monitor
    table is not freed by {hap,shadow}_teardown()'s loop.  This is caught by
    assertions later that we've successfully freed the entire hap/shadow memory
    pool.
    
    The per-vcpu loops in domain teardown logic is conceptually wrong, but exist
    due to insufficient existing structure in the existing logic.
    
    Break paging_vcpu_teardown() out of paging_teardown(), with mirrored breakouts
    in the hap/shadow code, and use it from arch_vcpu_create()'s error path.  This
    fixes the memory leak.
    
    The new {hap,shadow}_vcpu_teardown() must be idempotent, and are written to be
    as tolerable as possible, with the minimum number of safety checks possible.
    In particular, drop the mfn_valid() check - if these fields are junk, then Xen
    is going to explode anyway.
    
    Reported-by: Michał Leszczyński <michal.leszczynski@cert.pl>
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/domain.c           |  1 +
 xen/arch/x86/mm/hap/hap.c       | 39 ++++++++++++++++------------
 xen/arch/x86/mm/paging.c        |  8 ++++++
 xen/arch/x86/mm/shadow/common.c | 56 +++++++++++++++++++++++------------------
 xen/include/asm-x86/hap.h       |  1 +
 xen/include/asm-x86/paging.h    |  3 ++-
 xen/include/asm-x86/shadow.h    |  3 ++-
 7 files changed, 69 insertions(+), 42 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 4932ed62f1..b9ba04633e 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -588,6 +588,7 @@ int arch_vcpu_create(struct vcpu *v)
     return rc;
 
  fail:
+    paging_vcpu_teardown(v);
     vcpu_destroy_fpu(v);
     xfree(v->arch.msrs);
     v->arch.msrs = NULL;
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index 0fdb7d4a59..73575deb0d 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -563,30 +563,37 @@ void hap_final_teardown(struct domain *d)
     paging_unlock(d);
 }
 
+void hap_vcpu_teardown(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+    mfn_t mfn;
+
+    paging_lock(d);
+
+    if ( !paging_mode_hap(d) || !v->arch.paging.mode )
+        goto out;
+
+    mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+    if ( mfn_x(mfn) )
+        hap_destroy_monitor_table(v, mfn);
+    v->arch.hvm.monitor_table = pagetable_null();
+
+ out:
+    paging_unlock(d);
+}
+
 void hap_teardown(struct domain *d, bool *preempted)
 {
     struct vcpu *v;
-    mfn_t mfn;
 
     ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
-    paging_lock(d); /* Keep various asserts happy */
+    /* TODO - Remove when the teardown path is better structured. */
+    for_each_vcpu ( d, v )
+        hap_vcpu_teardown(v);
 
-    if ( paging_mode_enabled(d) )
-    {
-        /* release the monitor table held by each vcpu */
-        for_each_vcpu ( d, v )
-        {
-            if ( paging_get_hostmode(v) && paging_mode_external(d) )
-            {
-                mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
-                if ( mfn_valid(mfn) && (mfn_x(mfn) != 0) )
-                    hap_destroy_monitor_table(v, mfn);
-                v->arch.hvm.monitor_table = pagetable_null();
-            }
-        }
-    }
+    paging_lock(d); /* Keep various asserts happy */
 
     if ( d->arch.paging.hap.total_pages != 0 )
     {
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index 3aaec2ee3a..8bc14df943 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -794,6 +794,14 @@ long paging_domctl_continuation(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
 }
 #endif /* PG_log_dirty */
 
+void paging_vcpu_teardown(struct vcpu *v)
+{
+    if ( hap_enabled(v->domain) )
+        hap_vcpu_teardown(v);
+    else
+        shadow_vcpu_teardown(v);
+}
+
 /* Call when destroying a domain */
 int paging_teardown(struct domain *d)
 {
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index a33e100861..3298711972 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -2779,6 +2779,34 @@ int shadow_enable(struct domain *d, u32 mode)
     return rv;
 }
 
+void shadow_vcpu_teardown(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+
+    paging_lock(d);
+
+    if ( !paging_mode_shadow(d) || !v->arch.paging.mode )
+        goto out;
+
+    v->arch.paging.mode->shadow.detach_old_tables(v);
+#ifdef CONFIG_HVM
+    if ( shadow_mode_external(d) )
+    {
+        mfn_t mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+
+        if ( mfn_x(mfn) )
+            sh_destroy_monitor_table(
+                v, mfn,
+                v->arch.paging.mode->shadow.shadow_levels);
+
+        v->arch.hvm.monitor_table = pagetable_null();
+    }
+#endif
+
+ out:
+    paging_unlock(d);
+}
+
 void shadow_teardown(struct domain *d, bool *preempted)
 /* Destroy the shadow pagetables of this domain and free its shadow memory.
  * Should only be called for dying domains. */
@@ -2789,31 +2817,11 @@ void shadow_teardown(struct domain *d, bool *preempted)
     ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
-    paging_lock(d);
-
-    if ( shadow_mode_enabled(d) )
-    {
-        /* Release the shadow and monitor tables held by each vcpu */
-        for_each_vcpu(d, v)
-        {
-            if ( v->arch.paging.mode )
-            {
-                v->arch.paging.mode->shadow.detach_old_tables(v);
-#ifdef CONFIG_HVM
-                if ( shadow_mode_external(d) )
-                {
-                    mfn_t mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+    /* TODO - Remove when the teardown path is better structured. */
+    for_each_vcpu ( d, v )
+        shadow_vcpu_teardown(v);
 
-                    if ( mfn_valid(mfn) && (mfn_x(mfn) != 0) )
-                        sh_destroy_monitor_table(
-                            v, mfn,
-                            v->arch.paging.mode->shadow.shadow_levels);
-                    v->arch.hvm.monitor_table = pagetable_null();
-                }
-#endif /* CONFIG_HVM */
-            }
-        }
-    }
+    paging_lock(d);
 
 #if (SHADOW_OPTIMIZATIONS & (SHOPT_VIRTUAL_TLB|SHOPT_OUT_OF_SYNC))
     /* Free the virtual-TLB array attached to each vcpu */
diff --git a/xen/include/asm-x86/hap.h b/xen/include/asm-x86/hap.h
index d489df3812..90dece29de 100644
--- a/xen/include/asm-x86/hap.h
+++ b/xen/include/asm-x86/hap.h
@@ -36,6 +36,7 @@ int   hap_domctl(struct domain *d, struct xen_domctl_shadow_op *sc,
                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 int   hap_enable(struct domain *d, u32 mode);
 void  hap_final_teardown(struct domain *d);
+void  hap_vcpu_teardown(struct vcpu *v);
 void  hap_teardown(struct domain *d, bool *preempted);
 void  hap_vcpu_init(struct vcpu *v);
 int   hap_track_dirty_vram(struct domain *d,
diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h
index 5cf128cf34..7332a9b506 100644
--- a/xen/include/asm-x86/paging.h
+++ b/xen/include/asm-x86/paging.h
@@ -237,7 +237,8 @@ int paging_domctl(struct domain *d, struct xen_domctl_shadow_op *sc,
 /* Helper hypercall for dealing with continuations. */
 long paging_domctl_continuation(XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
 
-/* Call when destroying a domain */
+/* Call when destroying a vcpu/domain */
+void paging_vcpu_teardown(struct vcpu *v);
 int paging_teardown(struct domain *d);
 
 /* Call once all of the references to the domain have gone away */
diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index 76e47f257f..29a86ed78e 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -74,7 +74,8 @@ int shadow_domctl(struct domain *d,
                   struct xen_domctl_shadow_op *sc,
                   XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 
-/* Call when destroying a domain */
+/* Call when destroying a vcpu/domain */
+void shadow_vcpu_teardown(struct vcpu *v);
 void shadow_teardown(struct domain *d, bool *preempted);
 
 /* Call once all of the references to the domain have gone away */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 21 15:22:09 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 21 Dec 2020 15:22:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57404.100423 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krN0f-0000mF-W9; Mon, 21 Dec 2020 15:22:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57404.100423; Mon, 21 Dec 2020 15:22:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krN0f-0000m7-T2; Mon, 21 Dec 2020 15:22:05 +0000
Received: by outflank-mailman (input) for mailman id 57404;
 Mon, 21 Dec 2020 15:22:04 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krN0e-0000m0-RJ
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 15:22:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krN0e-0007ri-On
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 15:22:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krN0e-0005MD-Ne
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 15:22:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=i4R6HUw7Tk4Ja4QGTbxNq6ekx4qnS0p3lmFCpI3I3Qk=; b=rDTdqNGiQFS3erxfe4IEEAEq/B
	T8AidbPSqMtZQo/sS5vU9VFGB8rOD4N+Bn9rXth+N3d9LCFZZ679fjV28SK4fXyYSKhzSDcegderh
	5w+ld7cVuU2WXCFYVz/is9IWLJ4wFlgGdkXRdSyF9nZyp4er9h+RoX3AFRK9XyheZq+w=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/shadow: Fix build with !CONFIG_SHADOW_PAGING
Message-Id: <E1krN0e-0005MD-Ne@xenbits.xenproject.org>
Date: Mon, 21 Dec 2020 15:22:04 +0000

commit ffa9d2999722a404d3a4381b0249d191de134d33
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Dec 21 14:52:26 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 15:16:31 2020 +0000

    x86/shadow: Fix build with !CONFIG_SHADOW_PAGING
    
    Implement a stub for shadow_vcpu_teardown()
    
    Fixes: d162f36848c4 ("xen/x86: Fix memory leak in vcpu_create() error path")
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/asm-x86/shadow.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index 29a86ed78e..e25f9604d8 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -99,6 +99,7 @@ int shadow_set_allocation(struct domain *d, unsigned int pages,
 
 #else /* !CONFIG_SHADOW_PAGING */
 
+#define shadow_vcpu_teardown(v) ASSERT(is_pv_vcpu(v))
 #define shadow_teardown(d, p) ASSERT(is_pv_domain(d))
 #define shadow_final_teardown(d) ASSERT(is_pv_domain(d))
 #define shadow_enable(d, mode) \
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Mon Dec 21 22:44:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Mon, 21 Dec 2020 22:44:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57589.100836 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krTuQ-0007pv-B6; Mon, 21 Dec 2020 22:44:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57589.100836; Mon, 21 Dec 2020 22:44:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krTuQ-0007pn-86; Mon, 21 Dec 2020 22:44:06 +0000
Received: by outflank-mailman (input) for mailman id 57589;
 Mon, 21 Dec 2020 22:44:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krTuO-0007pi-Uy
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 22:44:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krTuO-0007Ls-T5
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 22:44:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krTuO-0002bq-Qo
 for xen-changelog@lists.xenproject.org; Mon, 21 Dec 2020 22:44:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=iFsyaIHkEGAS0iOUHLDnlXsACFbgrsDiAS/Us7Si6YU=; b=wQYlgzAJYKmMqWtYFta44OyyeB
	qBW8MHUuaHxq/sfim6NU02OZwVQRmCRaRXWbyB9NHlYzPCGhZQa3NOlXhH3HfIpsIjdJe9xcnJlYD
	+A6JoDHApLG5X16u972qYKWQUWjSQlSx7zdvC4xrKqWEq+sFb0qCdlC81Gtl+BUTm5rU=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen: Rework WARN_ON() to return whether a warning was triggered
Message-Id: <E1krTuO-0002bq-Qo@xenbits.xenproject.org>
Date: Mon, 21 Dec 2020 22:44:04 +0000

commit 8c8938dcc1bd37dd61f705410053e08804ca2b55
Author:     Julien Grall <jgrall@amazon.com>
AuthorDate: Fri Dec 18 13:30:54 2020 +0000
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Mon Dec 21 14:39:38 2020 -0800

    xen: Rework WARN_ON() to return whether a warning was triggered
    
    So far, our implementation of WARN_ON() cannot be used in the following
    situation:
    
    if ( WARN_ON() )
        ...
    
    This is because WARN_ON() doesn't return whether a warning has been
    triggered. Such construciton can be handy if you want to print more
    information and also dump the stack trace.
    
    Therefore, rework the WARN_ON() implementation to return whether a
    warning was triggered. The idea was borrowed from Linux
    
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Stefano Stabellini <sstabellini@kernel.org>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/xen/lib.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index 48429b69b8..5841bd489c 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -23,7 +23,13 @@
 #include <asm/bug.h>
 
 #define BUG_ON(p)  do { if (unlikely(p)) BUG();  } while (0)
-#define WARN_ON(p) do { if (unlikely(p)) WARN(); } while (0)
+#define WARN_ON(p)  ({                  \
+    bool ret_warn_on_ = (p);            \
+                                        \
+    if ( unlikely(ret_warn_on_) )       \
+        WARN();                         \
+    unlikely(ret_warn_on_);             \
+})
 
 /* All clang versions supported by Xen have _Static_assert. */
 #if defined(__clang__) || \
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 08:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 08:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57671.100981 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krcl9-00061v-25; Tue, 22 Dec 2020 08:11:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57671.100981; Tue, 22 Dec 2020 08:11:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krcl8-00061n-VQ; Tue, 22 Dec 2020 08:11:06 +0000
Received: by outflank-mailman (input) for mailman id 57671;
 Tue, 22 Dec 2020 08:11:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krcl6-00061i-UP
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:04 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krcl6-0008Ho-QG
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:04 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krcl6-0000M9-O1
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=+eczEVxmSOnqDY15tdEdZ8mjbdysbX/g0snodZUK6LQ=; b=FfGG5t2GoJPklOy79n7l81xMGP
	EAFgNGaTSwXiLeSEzVpnLmK41eedwJRgjP4C0xVI6FW3jZmak+wXSnUW+LT8llKs8VxtpL9A6+WcU
	68boOulCLo1HR0t9hP2H2qwfhK2QgLDxVR6NqJcH2I86Jbdb9mWdX/9YO3nnH63eDeQM=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86: verify function type (and maybe attribute) in switch_stack_and_jump()
Message-Id: <E1krcl6-0000M9-O1@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 08:11:04 +0000

commit 1a050d69faffe42fd22dbe9c9c49e2228919148f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 08:57:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 08:57:19 2020 +0100

    x86: verify function type (and maybe attribute) in switch_stack_and_jump()
    
    It is imperative that the functions passed here are taking no arguments,
    return no values, and don't return in the first place. While the type
    can be checked uniformly, the attribute check is limited to gcc 9 and
    newer (no clang support for this so far afaict).
    
    Note that I didn't want to have the "true" fallback "implementation" of
    __builtin_has_attribute(..., __noreturn__) generally available, as
    "true" may not be a suitable fallback in other cases.
    
    Note further that the noreturn addition to startup_cpu_idle_loop()'s
    declaration requires adding unreachable() to Arm's
    switch_stack_and_jump(), or else the build would break. I suppose this
    should have been there already.
    
    For vmx_asm_do_vmentry() along with adding the attribute, also restrict
    its scope.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/arch/x86/hvm/svm/svm.c        | 2 +-
 xen/arch/x86/hvm/vmx/vmcs.c       | 2 ++
 xen/arch/x86/setup.c              | 2 +-
 xen/include/asm-arm/current.h     | 6 ++++--
 xen/include/asm-x86/current.h     | 9 +++++++++
 xen/include/asm-x86/hvm/vmx/vmx.h | 1 -
 xen/include/xen/sched.h           | 2 +-
 7 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index d90627d4f7..0854fcfc14 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -63,7 +63,7 @@
 #include <asm/monitor.h>
 #include <asm/xstate.h>
 
-void svm_asm_do_resume(void);
+void noreturn svm_asm_do_resume(void);
 
 u32 svm_feature_flags;
 
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 1466064d0c..164535f8f0 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,6 +1850,8 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
+void noreturn vmx_asm_do_vmentry(void);
+
 void vmx_do_resume(void)
 {
     struct vcpu *v = current;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 1a2e5e41ab..5cdb0f0f92 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -619,7 +619,7 @@ static inline bool using_2M_mapping(void)
            !l1_table_offset((unsigned long)__2M_rwdata_end);
 }
 
-static void noinline init_done(void)
+static void noreturn init_done(void)
 {
     void *va;
     unsigned long start, end;
diff --git a/xen/include/asm-arm/current.h b/xen/include/asm-arm/current.h
index f71da9fab9..e7fbf535d2 100644
--- a/xen/include/asm-arm/current.h
+++ b/xen/include/asm-arm/current.h
@@ -43,8 +43,10 @@ static inline struct cpu_info *get_cpu_info(void)
 
 #define guest_cpu_user_regs() (&get_cpu_info()->guest_cpu_user_regs)
 
-#define switch_stack_and_jump(stack, fn)                                \
-    asm volatile ("mov sp,%0; b " STR(fn) : : "r" (stack) : "memory" )
+#define switch_stack_and_jump(stack, fn) do {                           \
+    asm volatile ("mov sp,%0; b " STR(fn) : : "r" (stack) : "memory" ); \
+    unreachable();                                                      \
+} while ( false )
 
 #define reset_stack_and_jump(fn) switch_stack_and_jump(get_cpu_info(), fn)
 
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 231994a245..5d690ce014 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -163,9 +163,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
+#if __GNUC__ >= 9
+# define ssaj_has_attr_noreturn(fn) __builtin_has_attribute(fn, __noreturn__)
+#else
+/* Simply can't check the property with older gcc. */
+# define ssaj_has_attr_noreturn(fn) true
+#endif
+
 #define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
+        (void)((fn) == (void (*)(void))NULL);                           \
+        BUILD_BUG_ON(!ssaj_has_attr_noreturn(fn));                      \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 09ea0fa2cd..534e9fc221 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -93,7 +93,6 @@ typedef enum {
 #define PI_xAPIC_NDST_MASK      0xFF00
 
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
-void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
 void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index faf5fda36f..76af29e932 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -736,7 +736,7 @@ void sched_context_switched(struct vcpu *prev, struct vcpu *vnext);
 void continue_running(
     struct vcpu *same);
 
-void startup_cpu_idle_loop(void);
+void noreturn startup_cpu_idle_loop(void);
 extern void (*pm_idle) (void);
 extern void (*dead_idle) (void);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 08:11:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 08:11:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57672.100984 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krclI-00063L-3V; Tue, 22 Dec 2020 08:11:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57672.100984; Tue, 22 Dec 2020 08:11:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krclI-00063D-0a; Tue, 22 Dec 2020 08:11:16 +0000
Received: by outflank-mailman (input) for mailman id 57672;
 Tue, 22 Dec 2020 08:11:14 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclG-00062f-Tt
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:14 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclG-0008ID-T5
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:14 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclG-0000N7-SG
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:14 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bW+z7Tb/RfOdoXDxzDSlwXKN7+nhSj/jRMwP1K3bcD8=; b=Kh6T2Hwwj/pWIaX1+Nx1E86hA+
	T20krbTQsk/jAxnGzySbdJ24Gu8F3nF875nyiz+It93RrLFzzCkotTjBIyHnEURuqyd3VZ0SgAtXJ
	aZDRK0lrtMwDUj3M/raUqih3hzh/VhxeIyFDTnBCTkb1rlO3KsgkhqNvItfMWla2zjNs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/EFI: don't insert timestamp when SOURCE_DATE_EPOCH is defined
Message-Id: <E1krclG-0000N7-SG@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 08:11:14 +0000

commit ee41b5c450032ae7f2531e18cd0a73bf5fb48803
Author:     Maximilian Engelhardt <maxi@daemonizer.de>
AuthorDate: Tue Dec 22 08:59:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 08:59:14 2020 +0100

    x86/EFI: don't insert timestamp when SOURCE_DATE_EPOCH is defined
    
    By default a timestamp gets added to the xen efi binary. Unfortunately
    ld doesn't seem to provide a way to set a custom date, like from
    SOURCE_DATE_EPOCH, so set a zero value for the timestamp (option
    --no-insert-timestamp) if SOURCE_DATE_EPOCH is defined. This makes
    reproducible builds possible.
    
    This is an alternative to the patch suggested in [1]. This patch only
    omits the timestamp when SOURCE_DATE_EPOCH is defined.
    
    [1] https://lists.xenproject.org/archives/html/xen-devel/2020-10/msg02161.html
    
    Signed-off-by: Maximilian Engelhardt <maxi@daemonizer.de>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/Makefile | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 8f2180485b..863aed043f 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -184,6 +184,12 @@ EFI_LDFLAGS += --major-image-version=$(XEN_VERSION)
 EFI_LDFLAGS += --minor-image-version=$(XEN_SUBVERSION)
 EFI_LDFLAGS += --major-os-version=2 --minor-os-version=0
 EFI_LDFLAGS += --major-subsystem-version=2 --minor-subsystem-version=0
+# It seems ld unfortunately can't set a custom timestamp, so add a zero value
+# for the timestamp (option --no-insert-timestamp) if SOURCE_DATE_EPOCH is
+# defined to make reproducible builds possible.
+ifdef SOURCE_DATE_EPOCH
+EFI_LDFLAGS += --no-insert-timestamp
+endif
 
 $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A VIRT_START$$,,p')
 $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p')
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 08:11:26 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 08:11:26 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57673.100988 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krclS-000655-6Y; Tue, 22 Dec 2020 08:11:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57673.100988; Tue, 22 Dec 2020 08:11:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krclS-00064x-3i; Tue, 22 Dec 2020 08:11:26 +0000
Received: by outflank-mailman (input) for mailman id 57673;
 Tue, 22 Dec 2020 08:11:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclR-00064n-3Z
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclR-0008IM-2K
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krclQ-0000O2-VM
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 08:11:24 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=eo+iwACgCve2JDC3T/9Cq9Q0lN8IwZZbxhRa9UkF2kM=; b=qqTxN11KhMr7zCp4yxeB8hiCN4
	LMoBMyWMNXt36QPDr1nYa0Rji2nA8H+zlwJTUD/Wzaq58Hq8Sr2hwns+ZGyJbc0FxWjjYXmN7qHWJ
	3Qrwr6dufgQNZA8M13O0sQosz+ZhNHKNah9Y2gwzCG7aJfli0ECbicTrxLydxXozGVqA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/Intel: insert Tiger Lake model numbers
Message-Id: <E1krclQ-0000O2-VM@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 08:11:24 +0000

commit e93c3712d67098453760fd61c338cbf62dd08da1
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 09:00:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 09:00:03 2020 +0100

    x86/Intel: insert Tiger Lake model numbers
    
    Both match prior generation processors as far as LBR and C-state MSRs
    go (SDM rev 073). The if_pschange_mc erratum, according to the spec
    update, is not applicable.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/acpi/cpu_idle.c | 3 +++
 xen/arch/x86/hvm/vmx/vmx.c   | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index 27e0b52621..c092086b33 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -183,6 +183,9 @@ static void do_get_hw_residencies(void *arg)
     /* Ice Lake */
     case 0x7D:
     case 0x7E:
+    /* Tiger Lake */
+    case 0x8C:
+    case 0x8D:
     /* Kaby Lake */
     case 0x8E:
     case 0x9E:
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 86b8916a5d..2d4475ee3d 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2776,6 +2776,8 @@ static const struct lbr_info *last_branch_msr_get(void)
         case 0x7a:
         /* Ice Lake */
         case 0x7d: case 0x7e:
+        /* Tiger Lake */
+        case 0x8c: case 0x8d:
         /* Tremont */
         case 0x86:
         /* Kaby Lake */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 11:11:11 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 11:11:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57761.101194 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krfZK-00068F-NV; Tue, 22 Dec 2020 11:11:06 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57761.101194; Tue, 22 Dec 2020 11:11:06 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krfZK-000687-KP; Tue, 22 Dec 2020 11:11:06 +0000
Received: by outflank-mailman (input) for mailman id 57761;
 Tue, 22 Dec 2020 11:11:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krfZJ-000681-4q
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 11:11:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krfZJ-0002vS-04
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 11:11:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krfZI-0002UU-VC
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 11:11:04 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=AZietJpv+fam0ibQR43tGJZBO4Bz0nFJuMlrBJ1mX2M=; b=OfyCZ1ibaV+i/5yYI06J8eHL6/
	jE1ATK0hR9QazI59IzA4WZhEJsHi6rOJwkgQp1QHK5e3p6LGdPoNU84UZktoJaYRkPpLAlDTjMwF2
	I6UQlJw+cuW3zZwKeCgQ2KjOXoFHS3QeTUPkRAnLE47EDKk+qf/7db6S7sd3nHpKgNKg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/mm: p2m_add_foreign() is HVM-only
Message-Id: <E1krfZI-0002UU-VC@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 11:11:04 +0000

commit d4f699a0df6cea907c1de5c277500b98c0729685
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 12:01:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 12:01:12 2020 +0100

    x86/mm: p2m_add_foreign() is HVM-only
    
    This is the case also for xenmem_add_to_physmap_one(), as is it's only
    caller of the function. Move the latter next to p2m_add_foreign(),
    allowing it one to become static at the same time. While moving, adjust
    indentation of the body of the main switch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 -----------------------------------------
 xen/arch/x86/mm/p2m.c     | 124 ++++++++++++++++++++++++++++++++++++++++++++--
 xen/common/memory.c       |   6 ++-
 xen/include/asm-x86/p2m.h |   4 --
 4 files changed, 125 insertions(+), 121 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 723cc1070f..79acf20c4e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,7 +118,6 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
-#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -142,10 +141,7 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
-
-#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
-#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4591,114 +4587,6 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-        case XENMAPSPACE_shared_info:
-            if ( idx == 0 )
-                mfn = virt_to_mfn(d->shared_info);
-            break;
-        case XENMAPSPACE_grant_table:
-            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-            if ( rc )
-                return rc;
-            break;
-        case XENMAPSPACE_gmfn:
-        {
-            p2m_type_t p2mt;
-
-            gfn = idx;
-            mfn = get_gfn_unshare(d, gfn, &p2mt);
-            /* If the page is still shared, exit early */
-            if ( p2m_is_shared(p2mt) )
-            {
-                put_gfn(d, gfn);
-                return -ENOMEM;
-            }
-            page = get_page_from_mfn(mfn, d);
-            if ( unlikely(!page) )
-                mfn = INVALID_MFN;
-            break;
-        }
-        case XENMAPSPACE_gmfn_foreign:
-            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-        default:
-            break;
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4caa666def..487959b121 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,6 +27,7 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
+#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -42,6 +43,10 @@
 
 #include "mm-locks.h"
 
+/* Override macro from asm/page.h to make work with mfn_t */
+#undef virt_to_mfn
+#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
+
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2540,6 +2545,8 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
+#ifdef CONFIG_HVM
+
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2556,8 +2563,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreigndom)
+static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                           unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2644,7 +2651,115 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-#ifdef CONFIG_HVM
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+    case XENMAPSPACE_shared_info:
+        if ( idx == 0 )
+            mfn = virt_to_mfn(d->shared_info);
+        break;
+
+    case XENMAPSPACE_grant_table:
+        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+        if ( rc )
+            return rc;
+        break;
+
+    case XENMAPSPACE_gmfn:
+    {
+        p2m_type_t p2mt;
+
+        gfn = idx;
+        mfn = get_gfn_unshare(d, gfn, &p2mt);
+        /* If the page is still shared, exit early */
+        if ( p2m_is_shared(p2mt) )
+        {
+            put_gfn(d, gfn);
+            return -ENOMEM;
+        }
+        page = get_page_from_mfn(mfn, d);
+        if ( unlikely(!page) )
+            mfn = INVALID_MFN;
+        break;
+    }
+
+    case XENMAPSPACE_gmfn_foreign:
+        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2797,7 +2912,8 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-#endif
+
+#endif /* CONFIG_HVM */
 
 /*
  * Local variables:
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 2c86934ae8..b21b6c452d 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -818,7 +818,11 @@ int xenmem_add_to_physmap(struct domain *d, struct xen_add_to_physmap *xatp,
     union add_to_physmap_extra extra = {};
     struct page_info *pages[16];
 
-    ASSERT(paging_mode_translate(d));
+    if ( !paging_mode_translate(d) )
+    {
+        ASSERT_UNREACHABLE();
+        return -EACCES;
+    }
 
     if ( xatp->space == XENMAPSPACE_gmfn_foreign )
         extra.foreign_domid = DOMID_INVALID;
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 8d6fd1aa01..6447696bcd 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,10 +661,6 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
-/* Add foreign mapping to the guest's p2m table. */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreign_domid);
-
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 14:44:16 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 14:44:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57881.101476 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritT-0000U5-6h; Tue, 22 Dec 2020 14:44:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57881.101476; Tue, 22 Dec 2020 14:44:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritT-0000Tx-3m; Tue, 22 Dec 2020 14:44:07 +0000
Received: by outflank-mailman (input) for mailman id 57881;
 Tue, 22 Dec 2020 14:44:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritR-0000Ts-8Y
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritR-0000pv-6R
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritR-0005wd-53
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=b0KPfCOg2Kzf/Ue8HN+uAHYQENOYgHSNSGvdGcm3yg4=; b=EDi8LRCOn+h13ZkniAYjH4v3vV
	gy7vnfcSb2sD60DxL4dxlHecuiVQZ0maUAUzcdJMcdTwlJlfhY+RLM21YIh1WBfe7aQYaPv5hKBTE
	ijmcxpb0cAhjPf9pBrsYa7qNwFkWYfNonpUAEd7rkw0nvKVg7hehE8X1udvApIiGzg04=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] docs: use predictable ordering in generated documentation
Message-Id: <E1kritR-0005wd-53@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 14:44:05 +0000

commit e18dadc5b709290b8038a1cacb52bc3b3b69cf21
Author:     Maximilian Engelhardt <maxi@daemonizer.de>
AuthorDate: Fri Dec 18 21:42:34 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 13:36:58 2020 +0000

    docs: use predictable ordering in generated documentation
    
    When the seq number is equal, sort by the title to get predictable
    output ordering. This is useful for reproducible builds.
    
    Signed-off-by: Maximilian Engelhardt <maxi@daemonizer.de>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 docs/xen-headers | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/xen-headers b/docs/xen-headers
index 54155632c4..8c434d77e2 100755
--- a/docs/xen-headers
+++ b/docs/xen-headers
@@ -331,7 +331,7 @@ sub output_index () {
 <h2>Starting points</h2>
 <ul>
 END
-    foreach my $ic (sort { $a->{Seq} <=> $b->{Seq} } @incontents) {
+    foreach my $ic (sort { $a->{Seq} <=> $b->{Seq} or $a->{Title} cmp $b->{Title} } @incontents) {
         $o .= "<li><a href=\"$ic->{Href}\">$ic->{Title}</a></li>\n";
     }
     $o .= "</ul>\n";
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 14:44:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 14:44:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57882.101481 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritd-0000Uk-8L; Tue, 22 Dec 2020 14:44:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57882.101481; Tue, 22 Dec 2020 14:44:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritd-0000Uc-5K; Tue, 22 Dec 2020 14:44:17 +0000
Received: by outflank-mailman (input) for mailman id 57882;
 Tue, 22 Dec 2020 14:44:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritb-0000UM-Bo
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritb-0000py-AC
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritb-0005xJ-8U
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=jJpZdJ2qpL3t7Pm+AyriMU58ugek6TicWBM32JNkh5M=; b=kr0KwS1EiKm4f/W2xIR3e0poNi
	mPtsXJPrnoKzqs+pw5PMKf4VwtmK9IK8U9IBA7Ow9OUk76/AVKspQqbny/bShtvztO4NTRs4lbZ39
	jKWUV6sPJub6z23P4w1u4rwoBY+Y5zNTIuhdOdhRIb0Nwrm81HwQj2bbWp/DrDO9Odog=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/domain: Reorder trivial initialisation in early domain_create()
Message-Id: <E1kritb-0005xJ-8U@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 14:44:15 +0000

commit 8dfeef47947929ad8de85140d391640744d9aead
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 16:47:58 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 14:31:34 2020 +0000

    xen/domain: Reorder trivial initialisation in early domain_create()
    
    This improves the robustness of the error paths.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/domain.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 5ec48c3e19..54241b0064 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -391,25 +391,8 @@ struct domain *domain_create(domid_t domid,
 
     TRACE_1D(TRC_DOM0_DOM_ADD, d->domain_id);
 
-    /*
-     * Allocate d->vcpu[] and set ->max_vcpus up early.  Various per-domain
-     * resources want to be sized based on max_vcpus.
-     */
-    if ( !is_system_domain(d) )
-    {
-        err = -ENOMEM;
-        d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
-        if ( !d->vcpu )
-            goto fail;
-
-        d->max_vcpus = config->max_vcpus;
-    }
-
     lock_profile_register_struct(LOCKPROF_TYPE_PERDOM, d, domid);
 
-    if ( (err = xsm_alloc_security_domain(d)) != 0 )
-        goto fail;
-
     atomic_set(&d->refcnt, 1);
     RCU_READ_LOCK_INIT(&d->rcu_lock);
     spin_lock_init_prof(d, domain_lock);
@@ -434,6 +417,25 @@ struct domain *domain_create(domid_t domid,
     INIT_LIST_HEAD(&d->pdev_list);
 #endif
 
+    /* All error paths can depend on the above setup. */
+
+    /*
+     * Allocate d->vcpu[] and set ->max_vcpus up early.  Various per-domain
+     * resources want to be sized based on max_vcpus.
+     */
+    if ( !is_system_domain(d) )
+    {
+        err = -ENOMEM;
+        d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
+        if ( !d->vcpu )
+            goto fail;
+
+        d->max_vcpus = config->max_vcpus;
+    }
+
+    if ( (err = xsm_alloc_security_domain(d)) != 0 )
+        goto fail;
+
     err = -ENOMEM;
     if ( !zalloc_cpumask_var(&d->dirty_cpumask) )
         goto fail;
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 14:44:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 14:44:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.57883.101485 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritn-0000WJ-9a; Tue, 22 Dec 2020 14:44:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 57883.101485; Tue, 22 Dec 2020 14:44:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kritn-0000WC-6q; Tue, 22 Dec 2020 14:44:27 +0000
Received: by outflank-mailman (input) for mailman id 57883;
 Tue, 22 Dec 2020 14:44:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritl-0000W1-Ew
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritl-0000qL-DO
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kritl-0005xv-CQ
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 14:44:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ahWRLK9igRRIThnfMrInKOmgVwt4v38tKOnfhQBx5rc=; b=PSm7vuCJADxrkxP6DZSZZWMdTA
	Vn+HPZ7JGXGInIHUfTuCj6NOa1m4hj4/SGYmd9MgzNPpNHktu99WYxNh0tuk0I67NAHpmfnjpG6HG
	bmBDMfp9Y5Bv8dSOYnTouL3yVvu8wFhRLHJ5qh6zWiDcIYJE08lajJu/Ayv+hk/rKZAg=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen/domain: Introduce domain_teardown()
Message-Id: <E1kritl-0005xv-CQ@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 14:44:25 +0000

commit 98d4d6d8a6329ea3a8dcf8aab65acdd70c6397fc
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 18:14:53 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 14:31:34 2020 +0000

    xen/domain: Introduce domain_teardown()
    
    There is no common equivelent of domain_reliquish_resources(), which has
    caused various pieces of common cleanup to live in inappropriate
    places.
    
    Perhaps most obviously, evtchn_destroy() is called for every continuation of
    domain_reliquish_resources(), which can easily be thousands of times.
    
    Create domain_teardown() to be a new top level facility, and call it from the
    appropriate positions in domain_kill() and domain_create()'s error path.  The
    intention is for this to supersede domain_reliquish_resources() in due course.
    
    No change in behaviour yet.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/domain.c     | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/sched.h |  8 +++++++
 2 files changed, 68 insertions(+)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 54241b0064..d151be3f36 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -272,6 +272,59 @@ static int __init parse_extra_guest_irqs(const char *s)
 }
 custom_param("extra_guest_irqs", parse_extra_guest_irqs);
 
+/*
+ * Release resources held by a domain.  There may or may not be live
+ * references to the domain, and it may or may not be fully constructed.
+ *
+ * d->is_dying differing between DOMDYING_dying and DOMDYING_dead can be used
+ * to determine if live references to the domain exist, and also whether
+ * continuations are permitted.
+ *
+ * If d->is_dying is DOMDYING_dead, this must not return non-zero.
+ */
+static int domain_teardown(struct domain *d)
+{
+    BUG_ON(!d->is_dying);
+
+    /*
+     * This hypercall can take minutes of wallclock time to complete.  This
+     * logic implements a co-routine, stashing state in struct domain across
+     * hypercall continuation boundaries.
+     */
+    switch ( d->teardown.val )
+    {
+        /*
+         * Record the current progress.  Subsequent hypercall continuations
+         * will logically restart work from this point.
+         *
+         * PROGRESS() markers must not be in the middle of loops.  The loop
+         * variable isn't preserved across a continuation.
+         *
+         * To avoid redundant work, there should be a marker before each
+         * function which may return -ERESTART.
+         */
+#define PROGRESS(x)                             \
+        d->teardown.val = PROG_ ## x;           \
+        /* Fallthrough */                       \
+    case PROG_ ## x
+
+        enum {
+            PROG_done = 1,
+        };
+
+    case 0:
+    PROGRESS(done):
+        break;
+
+#undef PROGRESS
+
+    default:
+        BUG();
+    }
+
+    return 0;
+}
+
 /*
  * Destroy a domain once all references to it have been dropped.  Used either
  * from the RCU path, or from the domain_create() error path before the domain
@@ -552,6 +605,10 @@ struct domain *domain_create(domid_t domid,
     if ( init_status & INIT_watchdog )
         watchdog_domain_destroy(d);
 
+    /* Must not hit a continuation in this context. */
+    if ( domain_teardown(d) )
+        ASSERT_UNREACHABLE();
+
     _domain_destroy(d);
 
     return ERR_PTR(err);
@@ -732,6 +789,9 @@ int domain_kill(struct domain *d)
         domain_set_outstanding_pages(d, 0);
         /* fallthrough */
     case DOMDYING_dying:
+        rc = domain_teardown(d);
+        if ( rc )
+            break;
         rc = evtchn_destroy(d);
         if ( rc )
             break;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 76af29e932..3e46384a3c 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -525,6 +525,14 @@ struct domain
     /* Argo interdomain communication support */
     struct argo_domain *argo;
 #endif
+
+    /*
+     * Continuation information for domain_teardown().  All fields entirely
+     * private.
+     */
+    struct {
+        unsigned int val;
+    } teardown;
 };
 
 static inline struct page_list_head *page_to_list(
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 21:00:08 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 21:00:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58089.101974 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolH-0002CD-8O; Tue, 22 Dec 2020 21:00:03 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58089.101974; Tue, 22 Dec 2020 21:00:03 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolH-0002C3-4R; Tue, 22 Dec 2020 21:00:03 +0000
Received: by outflank-mailman (input) for mailman id 58089;
 Tue, 22 Dec 2020 21:00:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolG-0002Br-Sq
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolG-0007zU-R8
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolG-0007Yd-Pi
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=nGkxpT+Ul2ys4hite6z0bbaj4AuWQnaPQJuyNaxKXEQ=; b=UPEP6bxbOyLK3Y2rTK+qJtXw/8
	lHJwGi7/BpqQkZxMFc1lasihX+wb2gL3KnDjNiE+RU3xzHCwBVh2QgVRLIvsBQnok1XgLHF1UhtML
	7Xp6BOaxweXhG0zdGFU/yLZTD0AwAWm4pJiOMUqYe3zQDROOrXr1L/bmr90CS5d2h9Ww=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/Kconfig: Correct the NR_CPUS description
Message-Id: <E1krolG-0007Yd-Pi@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 21:00:02 +0000

commit 6131dab5f2c8059a0fc7fd884bc6d4ff78ba44c2
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Fri Dec 18 23:30:04 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 14:11:25 2020 +0000

    xen/Kconfig: Correct the NR_CPUS description
    
    The description "physical CPUs" is especially wrong, as it implies the number
    of sockets, which tops out at 8 on all but the very biggest servers.
    
    NR_CPUS is the number of logical entities the scheduler can use.
    
    Reported-by: hanetzer@startmail.com
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/Kconfig | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/arch/Kconfig b/xen/arch/Kconfig
index 1954d1c5c1..d144d4c8d3 100644
--- a/xen/arch/Kconfig
+++ b/xen/arch/Kconfig
@@ -1,11 +1,17 @@
 
 config NR_CPUS
-	int "Maximum number of physical CPUs"
+	int "Maximum number of CPUs"
 	range 1 4095
 	default "256" if X86
 	default "8" if ARM && RCAR3
 	default "4" if ARM && QEMU
 	default "4" if ARM && MPSOC
 	default "128" if ARM
-	---help---
-	  Specifies the maximum number of physical CPUs which Xen will support.
+	help
+	  Controls the build-time size of various arrays and bitmaps
+	  associated with multiple-cpu management.  It is the upper bound of
+	  the number of logical entities the scheduler can run code on.
+
+	  For CPU cores which support Simultaneous Multi-Threading or similar
+	  technologies, this the number of logical threads which Xen will
+	  support.
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 21:00:14 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 21:00:14 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58092.101978 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolS-0002fq-9X; Tue, 22 Dec 2020 21:00:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58092.101978; Tue, 22 Dec 2020 21:00:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolS-0002fi-6F; Tue, 22 Dec 2020 21:00:14 +0000
Received: by outflank-mailman (input) for mailman id 58092;
 Tue, 22 Dec 2020 21:00:13 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolR-0002fY-0Q
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:13 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolQ-0007zX-VT
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolQ-0007aH-TX
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=dSmNtGYt+a0EJlciXPOqcmv9/+i+J+N2a8YISU3addY=; b=kX5rgwxaC+7dHrTb6IAT/xZ3FA
	RxJsqlKWb8w1hcnOeSeT2Fa+R/NktSi/Uf2W9OgIRaGBbH/ZeLY4VrlInBaVGshO7RCzUXuR2Rt+u
	CVZNpmv7Kj4zi7eMbKZfbXhNmXYTqOSRJu2gLtGaxSEQ8lddSR4k3KDs89EY/5wQX3ws=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/x86: Fix memory leak in vcpu_create() error path
Message-Id: <E1krolQ-0007aH-TX@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 21:00:12 +0000

commit d162f36848c4a98a782cc05820b0aa7ec1ae297d
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 15:25:44 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 14:11:25 2020 +0000

    xen/x86: Fix memory leak in vcpu_create() error path
    
    Various paths in vcpu_create() end up calling paging_update_paging_modes(),
    which eventually allocate a monitor pagetable if one doesn't exist.
    
    However, an error in vcpu_create() results in the vcpu being cleaned up
    locally, and not put onto the domain's vcpu list.  Therefore, the monitor
    table is not freed by {hap,shadow}_teardown()'s loop.  This is caught by
    assertions later that we've successfully freed the entire hap/shadow memory
    pool.
    
    The per-vcpu loops in domain teardown logic is conceptually wrong, but exist
    due to insufficient existing structure in the existing logic.
    
    Break paging_vcpu_teardown() out of paging_teardown(), with mirrored breakouts
    in the hap/shadow code, and use it from arch_vcpu_create()'s error path.  This
    fixes the memory leak.
    
    The new {hap,shadow}_vcpu_teardown() must be idempotent, and are written to be
    as tolerable as possible, with the minimum number of safety checks possible.
    In particular, drop the mfn_valid() check - if these fields are junk, then Xen
    is going to explode anyway.
    
    Reported-by: Michał Leszczyński <michal.leszczynski@cert.pl>
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/domain.c           |  1 +
 xen/arch/x86/mm/hap/hap.c       | 39 ++++++++++++++++------------
 xen/arch/x86/mm/paging.c        |  8 ++++++
 xen/arch/x86/mm/shadow/common.c | 56 +++++++++++++++++++++++------------------
 xen/include/asm-x86/hap.h       |  1 +
 xen/include/asm-x86/paging.h    |  3 ++-
 xen/include/asm-x86/shadow.h    |  3 ++-
 7 files changed, 69 insertions(+), 42 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 4932ed62f1..b9ba04633e 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -588,6 +588,7 @@ int arch_vcpu_create(struct vcpu *v)
     return rc;
 
  fail:
+    paging_vcpu_teardown(v);
     vcpu_destroy_fpu(v);
     xfree(v->arch.msrs);
     v->arch.msrs = NULL;
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index 0fdb7d4a59..73575deb0d 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -563,30 +563,37 @@ void hap_final_teardown(struct domain *d)
     paging_unlock(d);
 }
 
+void hap_vcpu_teardown(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+    mfn_t mfn;
+
+    paging_lock(d);
+
+    if ( !paging_mode_hap(d) || !v->arch.paging.mode )
+        goto out;
+
+    mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+    if ( mfn_x(mfn) )
+        hap_destroy_monitor_table(v, mfn);
+    v->arch.hvm.monitor_table = pagetable_null();
+
+ out:
+    paging_unlock(d);
+}
+
 void hap_teardown(struct domain *d, bool *preempted)
 {
     struct vcpu *v;
-    mfn_t mfn;
 
     ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
-    paging_lock(d); /* Keep various asserts happy */
+    /* TODO - Remove when the teardown path is better structured. */
+    for_each_vcpu ( d, v )
+        hap_vcpu_teardown(v);
 
-    if ( paging_mode_enabled(d) )
-    {
-        /* release the monitor table held by each vcpu */
-        for_each_vcpu ( d, v )
-        {
-            if ( paging_get_hostmode(v) && paging_mode_external(d) )
-            {
-                mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
-                if ( mfn_valid(mfn) && (mfn_x(mfn) != 0) )
-                    hap_destroy_monitor_table(v, mfn);
-                v->arch.hvm.monitor_table = pagetable_null();
-            }
-        }
-    }
+    paging_lock(d); /* Keep various asserts happy */
 
     if ( d->arch.paging.hap.total_pages != 0 )
     {
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index 3aaec2ee3a..8bc14df943 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -794,6 +794,14 @@ long paging_domctl_continuation(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
 }
 #endif /* PG_log_dirty */
 
+void paging_vcpu_teardown(struct vcpu *v)
+{
+    if ( hap_enabled(v->domain) )
+        hap_vcpu_teardown(v);
+    else
+        shadow_vcpu_teardown(v);
+}
+
 /* Call when destroying a domain */
 int paging_teardown(struct domain *d)
 {
diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
index a33e100861..3298711972 100644
--- a/xen/arch/x86/mm/shadow/common.c
+++ b/xen/arch/x86/mm/shadow/common.c
@@ -2779,6 +2779,34 @@ int shadow_enable(struct domain *d, u32 mode)
     return rv;
 }
 
+void shadow_vcpu_teardown(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+
+    paging_lock(d);
+
+    if ( !paging_mode_shadow(d) || !v->arch.paging.mode )
+        goto out;
+
+    v->arch.paging.mode->shadow.detach_old_tables(v);
+#ifdef CONFIG_HVM
+    if ( shadow_mode_external(d) )
+    {
+        mfn_t mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+
+        if ( mfn_x(mfn) )
+            sh_destroy_monitor_table(
+                v, mfn,
+                v->arch.paging.mode->shadow.shadow_levels);
+
+        v->arch.hvm.monitor_table = pagetable_null();
+    }
+#endif
+
+ out:
+    paging_unlock(d);
+}
+
 void shadow_teardown(struct domain *d, bool *preempted)
 /* Destroy the shadow pagetables of this domain and free its shadow memory.
  * Should only be called for dying domains. */
@@ -2789,31 +2817,11 @@ void shadow_teardown(struct domain *d, bool *preempted)
     ASSERT(d->is_dying);
     ASSERT(d != current->domain);
 
-    paging_lock(d);
-
-    if ( shadow_mode_enabled(d) )
-    {
-        /* Release the shadow and monitor tables held by each vcpu */
-        for_each_vcpu(d, v)
-        {
-            if ( v->arch.paging.mode )
-            {
-                v->arch.paging.mode->shadow.detach_old_tables(v);
-#ifdef CONFIG_HVM
-                if ( shadow_mode_external(d) )
-                {
-                    mfn_t mfn = pagetable_get_mfn(v->arch.hvm.monitor_table);
+    /* TODO - Remove when the teardown path is better structured. */
+    for_each_vcpu ( d, v )
+        shadow_vcpu_teardown(v);
 
-                    if ( mfn_valid(mfn) && (mfn_x(mfn) != 0) )
-                        sh_destroy_monitor_table(
-                            v, mfn,
-                            v->arch.paging.mode->shadow.shadow_levels);
-                    v->arch.hvm.monitor_table = pagetable_null();
-                }
-#endif /* CONFIG_HVM */
-            }
-        }
-    }
+    paging_lock(d);
 
 #if (SHADOW_OPTIMIZATIONS & (SHOPT_VIRTUAL_TLB|SHOPT_OUT_OF_SYNC))
     /* Free the virtual-TLB array attached to each vcpu */
diff --git a/xen/include/asm-x86/hap.h b/xen/include/asm-x86/hap.h
index d489df3812..90dece29de 100644
--- a/xen/include/asm-x86/hap.h
+++ b/xen/include/asm-x86/hap.h
@@ -36,6 +36,7 @@ int   hap_domctl(struct domain *d, struct xen_domctl_shadow_op *sc,
                  XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 int   hap_enable(struct domain *d, u32 mode);
 void  hap_final_teardown(struct domain *d);
+void  hap_vcpu_teardown(struct vcpu *v);
 void  hap_teardown(struct domain *d, bool *preempted);
 void  hap_vcpu_init(struct vcpu *v);
 int   hap_track_dirty_vram(struct domain *d,
diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h
index 5cf128cf34..7332a9b506 100644
--- a/xen/include/asm-x86/paging.h
+++ b/xen/include/asm-x86/paging.h
@@ -237,7 +237,8 @@ int paging_domctl(struct domain *d, struct xen_domctl_shadow_op *sc,
 /* Helper hypercall for dealing with continuations. */
 long paging_domctl_continuation(XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
 
-/* Call when destroying a domain */
+/* Call when destroying a vcpu/domain */
+void paging_vcpu_teardown(struct vcpu *v);
 int paging_teardown(struct domain *d);
 
 /* Call once all of the references to the domain have gone away */
diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index 76e47f257f..29a86ed78e 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -74,7 +74,8 @@ int shadow_domctl(struct domain *d,
                   struct xen_domctl_shadow_op *sc,
                   XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 
-/* Call when destroying a domain */
+/* Call when destroying a vcpu/domain */
+void shadow_vcpu_teardown(struct vcpu *v);
 void shadow_teardown(struct domain *d, bool *preempted);
 
 /* Call once all of the references to the domain have gone away */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 21:00:24 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 21:00:24 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58093.101982 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolc-0002hk-BD; Tue, 22 Dec 2020 21:00:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58093.101982; Tue, 22 Dec 2020 21:00:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolc-0002hc-83; Tue, 22 Dec 2020 21:00:24 +0000
Received: by outflank-mailman (input) for mailman id 58093;
 Tue, 22 Dec 2020 21:00:23 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolb-0002hR-3c
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:23 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolb-000802-2p
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:23 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1krolb-0007b5-1E
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:23 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=cvgo0J+wjf0XkS5+MC4wfe8WHMbipnlC9yYewezp4AE=; b=uS+E40zpLqES85ySrVXb3UOcFo
	Stpzx/c4TKwlC8ZXWU5mIfq6DlmpxAxmwQ3RVU7MsmcY3tEO3BApJbabpsKBCar0zzR6H710mIrRB
	uA4x8HBxIUowipAu8xYYRAOk3nLOY4paUfsAwU9nJgrxhgLIxSP7B/4i3oiaxhBFxoNs=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/shadow: Fix build with !CONFIG_SHADOW_PAGING
Message-Id: <E1krolb-0007b5-1E@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 21:00:23 +0000

commit ffa9d2999722a404d3a4381b0249d191de134d33
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Dec 21 14:52:26 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Mon Dec 21 15:16:31 2020 +0000

    x86/shadow: Fix build with !CONFIG_SHADOW_PAGING
    
    Implement a stub for shadow_vcpu_teardown()
    
    Fixes: d162f36848c4 ("xen/x86: Fix memory leak in vcpu_create() error path")
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/asm-x86/shadow.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index 29a86ed78e..e25f9604d8 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -99,6 +99,7 @@ int shadow_set_allocation(struct domain *d, unsigned int pages,
 
 #else /* !CONFIG_SHADOW_PAGING */
 
+#define shadow_vcpu_teardown(v) ASSERT(is_pv_vcpu(v))
 #define shadow_teardown(d, p) ASSERT(is_pv_domain(d))
 #define shadow_final_teardown(d) ASSERT(is_pv_domain(d))
 #define shadow_enable(d, mode) \
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Tue Dec 22 21:00:34 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Tue, 22 Dec 2020 21:00:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58094.101986 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolm-0002jW-Do; Tue, 22 Dec 2020 21:00:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58094.101986; Tue, 22 Dec 2020 21:00:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1krolm-0002jO-Ao; Tue, 22 Dec 2020 21:00:34 +0000
Received: by outflank-mailman (input) for mailman id 58094;
 Tue, 22 Dec 2020 21:00:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kroll-0002jD-6Z
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kroll-00080C-5o
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:33 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kroll-0007bm-4s
 for xen-changelog@lists.xenproject.org; Tue, 22 Dec 2020 21:00:33 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=ofNqe/HrSpNGej38b4Qk/Z9m1lg63dsYSNCUsgT4oHM=; b=XVRW8wy/AMyGL4kywGhSKUQ47s
	heNR/6HoxZo9UO12JruRC2aNhkVH2ZyK06dq0TTS8gSQDEHUGc9xwQFzfObs1bN1GXjb4idn8XIlD
	8wTrTFTuGz7pPs8+18wckwGAEKAgUaU5LdzDWFyV/VKjSkkjuJbcDfbmTS6LaZu34FzQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen: Rework WARN_ON() to return whether a warning was triggered
Message-Id: <E1kroll-0007bm-4s@xenbits.xenproject.org>
Date: Tue, 22 Dec 2020 21:00:33 +0000

commit 8c8938dcc1bd37dd61f705410053e08804ca2b55
Author:     Julien Grall <jgrall@amazon.com>
AuthorDate: Fri Dec 18 13:30:54 2020 +0000
Commit:     Stefano Stabellini <sstabellini@kernel.org>
CommitDate: Mon Dec 21 14:39:38 2020 -0800

    xen: Rework WARN_ON() to return whether a warning was triggered
    
    So far, our implementation of WARN_ON() cannot be used in the following
    situation:
    
    if ( WARN_ON() )
        ...
    
    This is because WARN_ON() doesn't return whether a warning has been
    triggered. Such construciton can be handy if you want to print more
    information and also dump the stack trace.
    
    Therefore, rework the WARN_ON() implementation to return whether a
    warning was triggered. The idea was borrowed from Linux
    
    Signed-off-by: Julien Grall <jgrall@amazon.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
    Acked-by: Stefano Stabellini <sstabellini@kernel.org>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/include/xen/lib.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index 48429b69b8..5841bd489c 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -23,7 +23,13 @@
 #include <asm/bug.h>
 
 #define BUG_ON(p)  do { if (unlikely(p)) BUG();  } while (0)
-#define WARN_ON(p) do { if (unlikely(p)) WARN(); } while (0)
+#define WARN_ON(p)  ({                  \
+    bool ret_warn_on_ = (p);            \
+                                        \
+    if ( unlikely(ret_warn_on_) )       \
+        WARN();                         \
+    unlikely(ret_warn_on_);             \
+})
 
 /* All clang versions supported by Xen have _Static_assert. */
 #if defined(__clang__) || \
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58179.102140 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIa-0004Qe-IF; Wed, 23 Dec 2020 07:11:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58179.102140; Wed, 23 Dec 2020 07:11:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIa-0004QW-FB; Wed, 23 Dec 2020 07:11:04 +0000
Received: by outflank-mailman (input) for mailman id 58179;
 Wed, 23 Dec 2020 07:11:02 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIY-0004QR-Le
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:02 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIY-0000VB-If
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:02 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIY-0001kU-Hc
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:02 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=8owMYtus/zfGWpIW8J4+GY2DxniD7h3VXP6+Erf+c28=; b=vcHvBLytld7Go498ZRe6RxcazS
	VELk46HlA3T5BNHhbuUCIalkKjNlAaBY2Oa1IBcoL3cLJlrz+gKrFHLdcj6y/wEg1zc+eX1pK9SjK
	wjzLn0Wz50MH7eZuGu8op7RNXnLtDUzcciqdmSehcLQlSbVEYXusVftqgD0wxC+MHqhA=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86: verify function type (and maybe attribute) in switch_stack_and_jump()
Message-Id: <E1kryIY-0001kU-Hc@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:02 +0000

commit 1a050d69faffe42fd22dbe9c9c49e2228919148f
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 08:57:19 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 08:57:19 2020 +0100

    x86: verify function type (and maybe attribute) in switch_stack_and_jump()
    
    It is imperative that the functions passed here are taking no arguments,
    return no values, and don't return in the first place. While the type
    can be checked uniformly, the attribute check is limited to gcc 9 and
    newer (no clang support for this so far afaict).
    
    Note that I didn't want to have the "true" fallback "implementation" of
    __builtin_has_attribute(..., __noreturn__) generally available, as
    "true" may not be a suitable fallback in other cases.
    
    Note further that the noreturn addition to startup_cpu_idle_loop()'s
    declaration requires adding unreachable() to Arm's
    switch_stack_and_jump(), or else the build would break. I suppose this
    should have been there already.
    
    For vmx_asm_do_vmentry() along with adding the attribute, also restrict
    its scope.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Reviewed-by: Juergen Gross <jgross@suse.com>
    Reviewed-by: Wei Liu <wl@xen.org>
    Acked-by: Julien Grall <jgrall@amazon.com>
---
 xen/arch/x86/hvm/svm/svm.c        | 2 +-
 xen/arch/x86/hvm/vmx/vmcs.c       | 2 ++
 xen/arch/x86/setup.c              | 2 +-
 xen/include/asm-arm/current.h     | 6 ++++--
 xen/include/asm-x86/current.h     | 9 +++++++++
 xen/include/asm-x86/hvm/vmx/vmx.h | 1 -
 xen/include/xen/sched.h           | 2 +-
 7 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index d90627d4f7..0854fcfc14 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -63,7 +63,7 @@
 #include <asm/monitor.h>
 #include <asm/xstate.h>
 
-void svm_asm_do_resume(void);
+void noreturn svm_asm_do_resume(void);
 
 u32 svm_feature_flags;
 
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index 1466064d0c..164535f8f0 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1850,6 +1850,8 @@ void vmx_vmentry_failure(void)
     domain_crash(curr->domain);
 }
 
+void noreturn vmx_asm_do_vmentry(void);
+
 void vmx_do_resume(void)
 {
     struct vcpu *v = current;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 1a2e5e41ab..5cdb0f0f92 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -619,7 +619,7 @@ static inline bool using_2M_mapping(void)
            !l1_table_offset((unsigned long)__2M_rwdata_end);
 }
 
-static void noinline init_done(void)
+static void noreturn init_done(void)
 {
     void *va;
     unsigned long start, end;
diff --git a/xen/include/asm-arm/current.h b/xen/include/asm-arm/current.h
index f71da9fab9..e7fbf535d2 100644
--- a/xen/include/asm-arm/current.h
+++ b/xen/include/asm-arm/current.h
@@ -43,8 +43,10 @@ static inline struct cpu_info *get_cpu_info(void)
 
 #define guest_cpu_user_regs() (&get_cpu_info()->guest_cpu_user_regs)
 
-#define switch_stack_and_jump(stack, fn)                                \
-    asm volatile ("mov sp,%0; b " STR(fn) : : "r" (stack) : "memory" )
+#define switch_stack_and_jump(stack, fn) do {                           \
+    asm volatile ("mov sp,%0; b " STR(fn) : : "r" (stack) : "memory" ); \
+    unreachable();                                                      \
+} while ( false )
 
 #define reset_stack_and_jump(fn) switch_stack_and_jump(get_cpu_info(), fn)
 
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index 231994a245..5d690ce014 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -163,9 +163,18 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 # define SHADOW_STACK_WORK ""
 #endif
 
+#if __GNUC__ >= 9
+# define ssaj_has_attr_noreturn(fn) __builtin_has_attribute(fn, __noreturn__)
+#else
+/* Simply can't check the property with older gcc. */
+# define ssaj_has_attr_noreturn(fn) true
+#endif
+
 #define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
         unsigned int tmp;                                               \
+        (void)((fn) == (void (*)(void))NULL);                           \
+        BUILD_BUG_ON(!ssaj_has_attr_noreturn(fn));                      \
         __asm__ __volatile__ (                                          \
             SHADOW_STACK_WORK                                           \
             "mov %[stk], %%rsp;"                                        \
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 09ea0fa2cd..534e9fc221 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -93,7 +93,6 @@ typedef enum {
 #define PI_xAPIC_NDST_MASK      0xFF00
 
 void vmx_asm_vmexit_handler(struct cpu_user_regs);
-void vmx_asm_do_vmentry(void);
 void vmx_intr_assist(void);
 void noreturn vmx_do_resume(void);
 void vmx_vlapic_msr_changed(struct vcpu *v);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index faf5fda36f..76af29e932 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -736,7 +736,7 @@ void sched_context_switched(struct vcpu *prev, struct vcpu *vnext);
 void continue_running(
     struct vcpu *same);
 
-void startup_cpu_idle_loop(void);
+void noreturn startup_cpu_idle_loop(void);
 extern void (*pm_idle) (void);
 extern void (*dead_idle) (void);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58180.102144 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIj-0004RI-Jg; Wed, 23 Dec 2020 07:11:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58180.102144; Wed, 23 Dec 2020 07:11:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIj-0004RA-Gl; Wed, 23 Dec 2020 07:11:13 +0000
Received: by outflank-mailman (input) for mailman id 58180;
 Wed, 23 Dec 2020 07:11:12 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIi-0004Qv-ND
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:12 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIi-0000VG-MG
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:12 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIi-0001lK-Kn
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:12 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7/Yg7PjxNMIe/ABiKzlI0fSKWfQRwyinAn0QPUuMCwU=; b=LS1bi8V0KxYMQsvLm1HTpK2Y61
	BNNPVbUcx76uXEbsIA134GTWsP/+84zSU40ElbWBMLPJHIgKLIBaUJTdGqmx6uHg/pgL+NUfcdwfm
	ppTQSq3I/pVG+R+bxSCUYHVikZeLNn6bllONiJSq+DSRudGk336q2dqa6eTO15767q8o=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/EFI: don't insert timestamp when SOURCE_DATE_EPOCH is defined
Message-Id: <E1kryIi-0001lK-Kn@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:12 +0000

commit ee41b5c450032ae7f2531e18cd0a73bf5fb48803
Author:     Maximilian Engelhardt <maxi@daemonizer.de>
AuthorDate: Tue Dec 22 08:59:14 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 08:59:14 2020 +0100

    x86/EFI: don't insert timestamp when SOURCE_DATE_EPOCH is defined
    
    By default a timestamp gets added to the xen efi binary. Unfortunately
    ld doesn't seem to provide a way to set a custom date, like from
    SOURCE_DATE_EPOCH, so set a zero value for the timestamp (option
    --no-insert-timestamp) if SOURCE_DATE_EPOCH is defined. This makes
    reproducible builds possible.
    
    This is an alternative to the patch suggested in [1]. This patch only
    omits the timestamp when SOURCE_DATE_EPOCH is defined.
    
    [1] https://lists.xenproject.org/archives/html/xen-devel/2020-10/msg02161.html
    
    Signed-off-by: Maximilian Engelhardt <maxi@daemonizer.de>
    Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/Makefile | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 8f2180485b..863aed043f 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -184,6 +184,12 @@ EFI_LDFLAGS += --major-image-version=$(XEN_VERSION)
 EFI_LDFLAGS += --minor-image-version=$(XEN_SUBVERSION)
 EFI_LDFLAGS += --major-os-version=2 --minor-os-version=0
 EFI_LDFLAGS += --major-subsystem-version=2 --minor-subsystem-version=0
+# It seems ld unfortunately can't set a custom timestamp, so add a zero value
+# for the timestamp (option --no-insert-timestamp) if SOURCE_DATE_EPOCH is
+# defined to make reproducible builds possible.
+ifdef SOURCE_DATE_EPOCH
+EFI_LDFLAGS += --no-insert-timestamp
+endif
 
 $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A VIRT_START$$,,p')
 $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A ALT_START$$,,p')
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:23 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:23 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58181.102148 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIt-0004Sn-LU; Wed, 23 Dec 2020 07:11:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58181.102148; Wed, 23 Dec 2020 07:11:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryIt-0004Sf-IJ; Wed, 23 Dec 2020 07:11:23 +0000
Received: by outflank-mailman (input) for mailman id 58181;
 Wed, 23 Dec 2020 07:11:22 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIs-0004SX-Qc
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:22 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIs-0000VP-Pj
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:22 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryIs-0001m2-OO
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:22 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KlQ2mnZDPwEzhjIsHQSeRUBNmbcVWg1pvL/HKrEJCeQ=; b=2BRoz27cu/5J3AO8wFQwAAv5tY
	6etxI+Q9h1SZDqkb1xc/03OehSkRMQRVvxXeyo34dcRWNWC2hhwtu6xI6SWfO5GUQ2G9/SrvwruGx
	T1lIzBJrD1CCq/oqSft+AZgVHTm7ty7PuV7v3G//bzNObrQLE+umPvKY92iGcIE66sHI=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/Intel: insert Tiger Lake model numbers
Message-Id: <E1kryIs-0001m2-OO@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:22 +0000

commit e93c3712d67098453760fd61c338cbf62dd08da1
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 09:00:03 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 09:00:03 2020 +0100

    x86/Intel: insert Tiger Lake model numbers
    
    Both match prior generation processors as far as LBR and C-state MSRs
    go (SDM rev 073). The if_pschange_mc erratum, according to the spec
    update, is not applicable.
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/acpi/cpu_idle.c | 3 +++
 xen/arch/x86/hvm/vmx/vmx.c   | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index 27e0b52621..c092086b33 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -183,6 +183,9 @@ static void do_get_hw_residencies(void *arg)
     /* Ice Lake */
     case 0x7D:
     case 0x7E:
+    /* Tiger Lake */
+    case 0x8C:
+    case 0x8D:
     /* Kaby Lake */
     case 0x8E:
     case 0x9E:
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 86b8916a5d..2d4475ee3d 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2776,6 +2776,8 @@ static const struct lbr_info *last_branch_msr_get(void)
         case 0x7a:
         /* Ice Lake */
         case 0x7d: case 0x7e:
+        /* Tiger Lake */
+        case 0x8c: case 0x8d:
         /* Tremont */
         case 0x86:
         /* Kaby Lake */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:33 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58182.102151 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJ3-0004Uh-Ml; Wed, 23 Dec 2020 07:11:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58182.102151; Wed, 23 Dec 2020 07:11:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJ3-0004Ua-Jt; Wed, 23 Dec 2020 07:11:33 +0000
Received: by outflank-mailman (input) for mailman id 58182;
 Wed, 23 Dec 2020 07:11:33 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJ3-0004UR-06
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:33 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJ2-0000Vp-Ug
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:32 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJ2-0001mi-S8
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:32 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=FJuMO6xcKaxOkR8WJ+evl7xdbIZh9bs/uex1JaLGPnk=; b=rMmqdqOE+40ubGzFzRs3plahA6
	v0C+zlAK7ly4TRNg+3U6kc+cKkmObBh+MZgi5mI93poZxi/Zeki1NC+OwwqkxYeUf70Uhwtv4oIH9
	TmEoyfgODVgGXdGaF1inVb9j+VtAyWH4g65cmcsByjBaHrCRFbY0EZhnowlP58g9GATQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] x86/mm: p2m_add_foreign() is HVM-only
Message-Id: <E1kryJ2-0001mi-S8@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:32 +0000

commit d4f699a0df6cea907c1de5c277500b98c0729685
Author:     Jan Beulich <jbeulich@suse.com>
AuthorDate: Tue Dec 22 12:01:12 2020 +0100
Commit:     Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Dec 22 12:01:12 2020 +0100

    x86/mm: p2m_add_foreign() is HVM-only
    
    This is the case also for xenmem_add_to_physmap_one(), as is it's only
    caller of the function. Move the latter next to p2m_add_foreign(),
    allowing it one to become static at the same time. While moving, adjust
    indentation of the body of the main switch().
    
    Signed-off-by: Jan Beulich <jbeulich@suse.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c         | 112 -----------------------------------------
 xen/arch/x86/mm/p2m.c     | 124 ++++++++++++++++++++++++++++++++++++++++++++--
 xen/common/memory.c       |   6 ++-
 xen/include/asm-x86/p2m.h |   4 --
 4 files changed, 125 insertions(+), 121 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 723cc1070f..79acf20c4e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -118,7 +118,6 @@
 #include <xen/vmap.h>
 #include <xen/xmalloc.h>
 #include <xen/efi.h>
-#include <xen/grant_table.h>
 #include <xen/hypercall.h>
 #include <xen/mm.h>
 #include <asm/paging.h>
@@ -142,10 +141,7 @@
 #include <asm/pci.h>
 #include <asm/guest.h>
 #include <asm/hvm/ioreq.h>
-
-#include <asm/hvm/grant_table.h>
 #include <asm/pv/domain.h>
-#include <asm/pv/grant_table.h>
 #include <asm/pv/mm.h>
 
 #ifdef CONFIG_PV
@@ -4591,114 +4587,6 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return err || s > e ? err : _handle_iomem_range(s, e, p);
 }
 
-int xenmem_add_to_physmap_one(
-    struct domain *d,
-    unsigned int space,
-    union add_to_physmap_extra extra,
-    unsigned long idx,
-    gfn_t gpfn)
-{
-    struct page_info *page = NULL;
-    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
-    mfn_t prev_mfn;
-    int rc = 0;
-    mfn_t mfn = INVALID_MFN;
-    p2m_type_t p2mt;
-
-    switch ( space )
-    {
-        case XENMAPSPACE_shared_info:
-            if ( idx == 0 )
-                mfn = virt_to_mfn(d->shared_info);
-            break;
-        case XENMAPSPACE_grant_table:
-            rc = gnttab_map_frame(d, idx, gpfn, &mfn);
-            if ( rc )
-                return rc;
-            break;
-        case XENMAPSPACE_gmfn:
-        {
-            p2m_type_t p2mt;
-
-            gfn = idx;
-            mfn = get_gfn_unshare(d, gfn, &p2mt);
-            /* If the page is still shared, exit early */
-            if ( p2m_is_shared(p2mt) )
-            {
-                put_gfn(d, gfn);
-                return -ENOMEM;
-            }
-            page = get_page_from_mfn(mfn, d);
-            if ( unlikely(!page) )
-                mfn = INVALID_MFN;
-            break;
-        }
-        case XENMAPSPACE_gmfn_foreign:
-            return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
-        default:
-            break;
-    }
-
-    if ( mfn_eq(mfn, INVALID_MFN) )
-    {
-        rc = -EINVAL;
-        goto put_both;
-    }
-
-    /* Remove previously mapped page if it was present. */
-    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
-    if ( mfn_valid(prev_mfn) )
-    {
-        if ( is_special_page(mfn_to_page(prev_mfn)) )
-            /* Special pages are simply unhooked from this phys slot. */
-            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
-        else if ( !mfn_eq(mfn, prev_mfn) )
-            /* Normal domain memory is freed, to avoid leaking memory. */
-            rc = guest_remove_page(d, gfn_x(gpfn));
-    }
-    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
-    put_gfn(d, gfn_x(gpfn));
-
-    if ( rc )
-        goto put_both;
-
-    /* Unmap from old location, if any. */
-    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
-    ASSERT(!SHARED_M2P(old_gpfn));
-    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
-    {
-        rc = -EXDEV;
-        goto put_both;
-    }
-    if ( old_gpfn != INVALID_M2P_ENTRY )
-        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
-
-    /* Map at new location. */
-    if ( !rc )
-        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
-
- put_both:
-    /*
-     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
-     * We also may need to transfer ownership of the page reference to our
-     * caller.
-     */
-    if ( space == XENMAPSPACE_gmfn )
-    {
-        put_gfn(d, gfn);
-        if ( !rc && extra.ppage )
-        {
-            *extra.ppage = page;
-            page = NULL;
-        }
-    }
-
-    if ( page )
-        put_page(page);
-
-    return rc;
-}
-
 int arch_acquire_resource(struct domain *d, unsigned int type,
                           unsigned int id, unsigned long frame,
                           unsigned int nr_frames, xen_pfn_t mfn_list[])
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4caa666def..487959b121 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -27,6 +27,7 @@
 #include <xen/mem_access.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
+#include <xen/grant_table.h>
 #include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
@@ -42,6 +43,10 @@
 
 #include "mm-locks.h"
 
+/* Override macro from asm/page.h to make work with mfn_t */
+#undef virt_to_mfn
+#define virt_to_mfn(v) _mfn(__virt_to_mfn(v))
+
 /* Turn on/off host superpage page table support for hap, default on. */
 bool_t __initdata opt_hap_1gb = 1, __initdata opt_hap_2mb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
@@ -2540,6 +2545,8 @@ out_p2m_audit:
 }
 #endif /* P2M_AUDIT */
 
+#ifdef CONFIG_HVM
+
 /*
  * Add frame from foreign domain to target domain's physmap. Similar to
  * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
@@ -2556,8 +2563,8 @@ out_p2m_audit:
  *
  * Returns: 0 ==> success
  */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreigndom)
+static int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
+                           unsigned long gpfn, domid_t foreigndom)
 {
     p2m_type_t p2mt, p2mt_prev;
     mfn_t prev_mfn, mfn;
@@ -2644,7 +2651,115 @@ int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
     return rc;
 }
 
-#ifdef CONFIG_HVM
+int xenmem_add_to_physmap_one(
+    struct domain *d,
+    unsigned int space,
+    union add_to_physmap_extra extra,
+    unsigned long idx,
+    gfn_t gpfn)
+{
+    struct page_info *page = NULL;
+    unsigned long gfn = 0 /* gcc ... */, old_gpfn;
+    mfn_t prev_mfn;
+    int rc = 0;
+    mfn_t mfn = INVALID_MFN;
+    p2m_type_t p2mt;
+
+    switch ( space )
+    {
+    case XENMAPSPACE_shared_info:
+        if ( idx == 0 )
+            mfn = virt_to_mfn(d->shared_info);
+        break;
+
+    case XENMAPSPACE_grant_table:
+        rc = gnttab_map_frame(d, idx, gpfn, &mfn);
+        if ( rc )
+            return rc;
+        break;
+
+    case XENMAPSPACE_gmfn:
+    {
+        p2m_type_t p2mt;
+
+        gfn = idx;
+        mfn = get_gfn_unshare(d, gfn, &p2mt);
+        /* If the page is still shared, exit early */
+        if ( p2m_is_shared(p2mt) )
+        {
+            put_gfn(d, gfn);
+            return -ENOMEM;
+        }
+        page = get_page_from_mfn(mfn, d);
+        if ( unlikely(!page) )
+            mfn = INVALID_MFN;
+        break;
+    }
+
+    case XENMAPSPACE_gmfn_foreign:
+        return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+    }
+
+    if ( mfn_eq(mfn, INVALID_MFN) )
+    {
+        rc = -EINVAL;
+        goto put_both;
+    }
+
+    /* Remove previously mapped page if it was present. */
+    prev_mfn = get_gfn(d, gfn_x(gpfn), &p2mt);
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_special_page(mfn_to_page(prev_mfn)) )
+            /* Special pages are simply unhooked from this phys slot. */
+            rc = guest_physmap_remove_page(d, gpfn, prev_mfn, PAGE_ORDER_4K);
+        else if ( !mfn_eq(mfn, prev_mfn) )
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            rc = guest_remove_page(d, gfn_x(gpfn));
+    }
+    /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */
+    put_gfn(d, gfn_x(gpfn));
+
+    if ( rc )
+        goto put_both;
+
+    /* Unmap from old location, if any. */
+    old_gpfn = get_gpfn_from_mfn(mfn_x(mfn));
+    ASSERT(!SHARED_M2P(old_gpfn));
+    if ( space == XENMAPSPACE_gmfn && old_gpfn != gfn )
+    {
+        rc = -EXDEV;
+        goto put_both;
+    }
+    if ( old_gpfn != INVALID_M2P_ENTRY )
+        rc = guest_physmap_remove_page(d, _gfn(old_gpfn), mfn, PAGE_ORDER_4K);
+
+    /* Map at new location. */
+    if ( !rc )
+        rc = guest_physmap_add_page(d, gpfn, mfn, PAGE_ORDER_4K);
+
+ put_both:
+    /*
+     * In the XENMAPSPACE_gmfn case, we took a ref of the gfn at the top.
+     * We also may need to transfer ownership of the page reference to our
+     * caller.
+     */
+    if ( space == XENMAPSPACE_gmfn )
+    {
+        put_gfn(d, gfn);
+        if ( !rc && extra.ppage )
+        {
+            *extra.ppage = page;
+            page = NULL;
+        }
+    }
+
+    if ( page )
+        put_page(page);
+
+    return rc;
+}
+
 /*
  * Set/clear the #VE suppress bit for a page.  Only available on VMX.
  */
@@ -2797,7 +2912,8 @@ int p2m_set_altp2m_view_visibility(struct domain *d, unsigned int altp2m_idx,
 
     return rc;
 }
-#endif
+
+#endif /* CONFIG_HVM */
 
 /*
  * Local variables:
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 2c86934ae8..b21b6c452d 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -818,7 +818,11 @@ int xenmem_add_to_physmap(struct domain *d, struct xen_add_to_physmap *xatp,
     union add_to_physmap_extra extra = {};
     struct page_info *pages[16];
 
-    ASSERT(paging_mode_translate(d));
+    if ( !paging_mode_translate(d) )
+    {
+        ASSERT_UNREACHABLE();
+        return -EACCES;
+    }
 
     if ( xatp->space == XENMAPSPACE_gmfn_foreign )
         extra.foreign_domid = DOMID_INVALID;
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 8d6fd1aa01..6447696bcd 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -661,10 +661,6 @@ int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
 int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
-/* Add foreign mapping to the guest's p2m table. */
-int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-                    unsigned long gpfn, domid_t foreign_domid);
-
 /* 
  * Populate-on-demand
  */
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:43 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58183.102156 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJD-0004W9-Q3; Wed, 23 Dec 2020 07:11:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58183.102156; Wed, 23 Dec 2020 07:11:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJD-0004W2-N7; Wed, 23 Dec 2020 07:11:43 +0000
Received: by outflank-mailman (input) for mailman id 58183;
 Wed, 23 Dec 2020 07:11:43 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJD-0004Vv-4n
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:43 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJD-0000W2-39
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:43 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJD-0001nK-0O
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:43 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=OHxvU+6Ny32b6YWLWViUoIZ2G05cdJpPqZ69luNhIj0=; b=imCxu4IvZ5kk2da+ChEoGKSBLI
	80SRAVMsRBuq1mKJ2fZh0J/d8tT3+bI2aoRN5sRf+qQZ7UOGrj0+pvIizIw0zf+gbE5PR54p76Yp1
	qfrQ5yjXpQXpvxUMvE20pcMs8UA1uagCYB6i3sDaaXO0UuKs7Cc/6JdK0ZQY/Z3nTHo4=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] docs: use predictable ordering in generated documentation
Message-Id: <E1kryJD-0001nK-0O@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:43 +0000

commit e18dadc5b709290b8038a1cacb52bc3b3b69cf21
Author:     Maximilian Engelhardt <maxi@daemonizer.de>
AuthorDate: Fri Dec 18 21:42:34 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 13:36:58 2020 +0000

    docs: use predictable ordering in generated documentation
    
    When the seq number is equal, sort by the title to get predictable
    output ordering. This is useful for reproducible builds.
    
    Signed-off-by: Maximilian Engelhardt <maxi@daemonizer.de>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 docs/xen-headers | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/xen-headers b/docs/xen-headers
index 54155632c4..8c434d77e2 100755
--- a/docs/xen-headers
+++ b/docs/xen-headers
@@ -331,7 +331,7 @@ sub output_index () {
 <h2>Starting points</h2>
 <ul>
 END
-    foreach my $ic (sort { $a->{Seq} <=> $b->{Seq} } @incontents) {
+    foreach my $ic (sort { $a->{Seq} <=> $b->{Seq} or $a->{Title} cmp $b->{Title} } @incontents) {
         $o .= "<li><a href=\"$ic->{Href}\">$ic->{Title}</a></li>\n";
     }
     $o .= "</ul>\n";
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:11:54 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:11:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58186.102174 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJO-0004Zs-5Z; Wed, 23 Dec 2020 07:11:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58186.102174; Wed, 23 Dec 2020 07:11:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJO-0004Zm-2W; Wed, 23 Dec 2020 07:11:54 +0000
Received: by outflank-mailman (input) for mailman id 58186;
 Wed, 23 Dec 2020 07:11:53 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJN-0004ZV-7h
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:53 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJN-0000WF-6q
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:53 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJN-0001o3-5B
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:11:53 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=vUWEcMq89ZP0p2sNWFS9T1NLLLfYqYWVfyalOpIAVCo=; b=wiQFfyIS8spPexZaHaMOTasQLm
	bL/gRd0f5x8/uyQhWQCmglvQ7EHF254KpGQE251QFvVPyDr7CJZiuEKEhvCHMDyNbz+kg2MMB5pye
	mb6ONUIji5vLayBjU7St+U+ranOcTr+U9WsHL6mZcA4bQHccg49rp+eMADZ/TsFjMKKk=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/domain: Reorder trivial initialisation in early domain_create()
Message-Id: <E1kryJN-0001o3-5B@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:11:53 +0000

commit 8dfeef47947929ad8de85140d391640744d9aead
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 16:47:58 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 14:31:34 2020 +0000

    xen/domain: Reorder trivial initialisation in early domain_create()
    
    This improves the robustness of the error paths.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/domain.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 5ec48c3e19..54241b0064 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -391,25 +391,8 @@ struct domain *domain_create(domid_t domid,
 
     TRACE_1D(TRC_DOM0_DOM_ADD, d->domain_id);
 
-    /*
-     * Allocate d->vcpu[] and set ->max_vcpus up early.  Various per-domain
-     * resources want to be sized based on max_vcpus.
-     */
-    if ( !is_system_domain(d) )
-    {
-        err = -ENOMEM;
-        d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
-        if ( !d->vcpu )
-            goto fail;
-
-        d->max_vcpus = config->max_vcpus;
-    }
-
     lock_profile_register_struct(LOCKPROF_TYPE_PERDOM, d, domid);
 
-    if ( (err = xsm_alloc_security_domain(d)) != 0 )
-        goto fail;
-
     atomic_set(&d->refcnt, 1);
     RCU_READ_LOCK_INIT(&d->rcu_lock);
     spin_lock_init_prof(d, domain_lock);
@@ -434,6 +417,25 @@ struct domain *domain_create(domid_t domid,
     INIT_LIST_HEAD(&d->pdev_list);
 #endif
 
+    /* All error paths can depend on the above setup. */
+
+    /*
+     * Allocate d->vcpu[] and set ->max_vcpus up early.  Various per-domain
+     * resources want to be sized based on max_vcpus.
+     */
+    if ( !is_system_domain(d) )
+    {
+        err = -ENOMEM;
+        d->vcpu = xzalloc_array(struct vcpu *, config->max_vcpus);
+        if ( !d->vcpu )
+            goto fail;
+
+        d->max_vcpus = config->max_vcpus;
+    }
+
+    if ( (err = xsm_alloc_security_domain(d)) != 0 )
+        goto fail;
+
     err = -ENOMEM;
     if ( !zalloc_cpumask_var(&d->dirty_cpumask) )
         goto fail;
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Wed Dec 23 07:12:04 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Wed, 23 Dec 2020 07:12:04 +0000
Received: from list by lists.xenproject.org with outflank-mailman.58188.102178 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJY-0004eV-7M; Wed, 23 Dec 2020 07:12:04 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 58188.102178; Wed, 23 Dec 2020 07:12:04 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kryJY-0004eO-4E; Wed, 23 Dec 2020 07:12:04 +0000
Received: by outflank-mailman (input) for mailman id 58188;
 Wed, 23 Dec 2020 07:12:03 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJX-0004eB-Be
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:12:03 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJX-0000Wd-A4
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:12:03 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kryJX-0001pR-8u
 for xen-changelog@lists.xenproject.org; Wed, 23 Dec 2020 07:12:03 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=bvbTFWf/+cfYD3SFXWR0X/fs/m6PJc43OTPPVAbvE9Y=; b=nNdaU/5T4K/cz0+W5tHZIImtiQ
	HKlDYpFEMb2DNf20mSsvnth3Jev6N1YqnWY7CCgtlEjnjD+jA6cfQfrxrpqoN0Cqmcl0yxpzATZV4
	UTI/RoTeY+G5BXRxBW+rXMKXAiYD1MJ72FMSK8IjeEo8YM84+LECz9uWnzrAQySt6a4I=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen master] xen/domain: Introduce domain_teardown()
Message-Id: <E1kryJX-0001pR-8u@xenbits.xenproject.org>
Date: Wed, 23 Dec 2020 07:12:03 +0000

commit 98d4d6d8a6329ea3a8dcf8aab65acdd70c6397fc
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Mon Sep 28 18:14:53 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Tue Dec 22 14:31:34 2020 +0000

    xen/domain: Introduce domain_teardown()
    
    There is no common equivelent of domain_reliquish_resources(), which has
    caused various pieces of common cleanup to live in inappropriate
    places.
    
    Perhaps most obviously, evtchn_destroy() is called for every continuation of
    domain_reliquish_resources(), which can easily be thousands of times.
    
    Create domain_teardown() to be a new top level facility, and call it from the
    appropriate positions in domain_kill() and domain_create()'s error path.  The
    intention is for this to supersede domain_reliquish_resources() in due course.
    
    No change in behaviour yet.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/domain.c     | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/sched.h |  8 +++++++
 2 files changed, 68 insertions(+)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 54241b0064..d151be3f36 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -272,6 +272,59 @@ static int __init parse_extra_guest_irqs(const char *s)
 }
 custom_param("extra_guest_irqs", parse_extra_guest_irqs);
 
+/*
+ * Release resources held by a domain.  There may or may not be live
+ * references to the domain, and it may or may not be fully constructed.
+ *
+ * d->is_dying differing between DOMDYING_dying and DOMDYING_dead can be used
+ * to determine if live references to the domain exist, and also whether
+ * continuations are permitted.
+ *
+ * If d->is_dying is DOMDYING_dead, this must not return non-zero.
+ */
+static int domain_teardown(struct domain *d)
+{
+    BUG_ON(!d->is_dying);
+
+    /*
+     * This hypercall can take minutes of wallclock time to complete.  This
+     * logic implements a co-routine, stashing state in struct domain across
+     * hypercall continuation boundaries.
+     */
+    switch ( d->teardown.val )
+    {
+        /*
+         * Record the current progress.  Subsequent hypercall continuations
+         * will logically restart work from this point.
+         *
+         * PROGRESS() markers must not be in the middle of loops.  The loop
+         * variable isn't preserved across a continuation.
+         *
+         * To avoid redundant work, there should be a marker before each
+         * function which may return -ERESTART.
+         */
+#define PROGRESS(x)                             \
+        d->teardown.val = PROG_ ## x;           \
+        /* Fallthrough */                       \
+    case PROG_ ## x
+
+        enum {
+            PROG_done = 1,
+        };
+
+    case 0:
+    PROGRESS(done):
+        break;
+
+#undef PROGRESS
+
+    default:
+        BUG();
+    }
+
+    return 0;
+}
+
 /*
  * Destroy a domain once all references to it have been dropped.  Used either
  * from the RCU path, or from the domain_create() error path before the domain
@@ -552,6 +605,10 @@ struct domain *domain_create(domid_t domid,
     if ( init_status & INIT_watchdog )
         watchdog_domain_destroy(d);
 
+    /* Must not hit a continuation in this context. */
+    if ( domain_teardown(d) )
+        ASSERT_UNREACHABLE();
+
     _domain_destroy(d);
 
     return ERR_PTR(err);
@@ -732,6 +789,9 @@ int domain_kill(struct domain *d)
         domain_set_outstanding_pages(d, 0);
         /* fallthrough */
     case DOMDYING_dying:
+        rc = domain_teardown(d);
+        if ( rc )
+            break;
         rc = evtchn_destroy(d);
         if ( rc )
             break;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 76af29e932..3e46384a3c 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -525,6 +525,14 @@ struct domain
     /* Argo interdomain communication support */
     struct argo_domain *argo;
 #endif
+
+    /*
+     * Continuation information for domain_teardown().  All fields entirely
+     * private.
+     */
+    struct {
+        unsigned int val;
+    } teardown;
 };
 
 static inline struct page_list_head *page_to_list(
--
generated by git-patchbot for /home/xen/git/xen.git#master


From xen-changelog-bounces@lists.xenproject.org Thu Dec 31 18:00:13 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 31 Dec 2020 18:00:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.60595.106341 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2F5-0002hn-6o; Thu, 31 Dec 2020 18:00:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 60595.106341; Thu, 31 Dec 2020 18:00:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2F5-0002he-37; Thu, 31 Dec 2020 18:00:07 +0000
Received: by outflank-mailman (input) for mailman id 60595;
 Thu, 31 Dec 2020 18:00:05 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2F3-0002aM-Rc
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:05 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2F3-0003VB-Kn
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:05 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2F3-0000pw-Iy
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:05 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=7mBgnF1Uqa5OpVTQ70n5xLOQrX1aNWX1Wh5hz4VI31A=; b=VbBkKkgo+MFBnVMN+kxoWEswCs
	BqPGsexFmQ6O12DkVC6xw3NGshNJaH2YsXu/EPBS7KgRhgj7qwj7yaC/2UmQtHOba9zuuycJOC2I7
	CZyrNw/GywUTksDcFf4PVM3KF9/i9Xyw2i7aZduLDIZh9lJ5RrIT4DViek2jCN+Tk0ho=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/hpet: Fix return value of hpet_setup()
Message-Id: <E1kv2F3-0000pw-Iy@xenbits.xenproject.org>
Date: Thu, 31 Dec 2020 18:00:05 +0000

commit 83736c567d6b64dbce98f251ca72e7870f556421
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Tue Dec 29 17:51:23 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 31 16:19:00 2020 +0000

    x86/hpet: Fix return value of hpet_setup()
    
    hpet_setup() is idempotent if the rate has already been calculated, and
    returns the cached value.  However, this only works correctly when the return
    statements are identical.
    
    Use a sensibly named local variable, rather than a dead one with a bad name.
    
    Fixes: a60bb68219 ("x86/time: reduce rounding errors in calculations")
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/arch/x86/hpet.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c
index a55e68e6f7..e6fab8acd8 100644
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -759,7 +759,7 @@ u64 __init hpet_setup(void)
 {
     static u64 __initdata hpet_rate;
     u32 hpet_id, hpet_period;
-    unsigned int last;
+    unsigned int last, rem;
 
     if ( hpet_rate )
         return hpet_rate;
@@ -789,9 +789,11 @@ u64 __init hpet_setup(void)
     hpet_resume(hpet_boot_cfg);
 
     hpet_rate = 1000000000000000ULL; /* 10^15 */
-    last = do_div(hpet_rate, hpet_period);
+    rem = do_div(hpet_rate, hpet_period);
+    if ( (rem * 2) > hpet_period )
+        hpet_rate++;
 
-    return hpet_rate + (last * 2 > hpet_period);
+    return hpet_rate;
 }
 
 void hpet_resume(u32 *boot_cfg)
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 31 18:00:17 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 31 Dec 2020 18:00:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.60596.106345 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2FF-0002mN-7n; Thu, 31 Dec 2020 18:00:17 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 60596.106345; Thu, 31 Dec 2020 18:00:17 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2FF-0002mF-4b; Thu, 31 Dec 2020 18:00:17 +0000
Received: by outflank-mailman (input) for mailman id 60596;
 Thu, 31 Dec 2020 18:00:15 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FD-0002m4-Pk
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:15 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FD-0003VH-Ov
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:15 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FD-0000sH-N5
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:15 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=KwZf3Wy2MAkMW/fDdIMEe6muFEbWbQHqhS5mPxmzDkU=; b=jXeTvTsNRBO3Zdynm3aRM//QJw
	wyhOpZ6Zdqj7XJAGZy1nj692XN3FflMJ1NOYR5EJXz1pFoKA7JxBnaEA44qLbrJ+fgGLFP9/w+VDL
	MGOH0UaqIq1of+hOAX3/ihdfIzrZ1Fngwfsm7gfaGNbMTvgTenCE6bcLmq7cY9JmQAUo=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] x86/svm: Clean up MSR_K8_VM_CR definitions
Message-Id: <E1kv2FD-0000sH-N5@xenbits.xenproject.org>
Date: Thu, 31 Dec 2020 18:00:15 +0000

commit 8cefa4b8de4113df58783081d201490ac83a19de
Author:     Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Wed Dec 30 19:26:14 2020 +0000
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 31 16:19:00 2020 +0000

    x86/svm: Clean up MSR_K8_VM_CR definitions
    
    Drop the unused shift number, and reposition the constants into the cleaned-up
    section.  Rename VM_CR_SVM_DISABLE to be closer to its APM definition.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
    Acked-by: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/arch/x86/hvm/svm/svm.c      | 2 +-
 xen/include/asm-x86/msr-index.h | 8 +++-----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 0854fcfc14..b819897a4a 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1586,7 +1586,7 @@ static int _svm_cpu_up(bool bsp)
 
     /* Check whether SVM feature is disabled in BIOS */
     rdmsrl(MSR_K8_VM_CR, msr_content);
-    if ( msr_content & K8_VMCR_SVME_DISABLE )
+    if ( msr_content & VM_CR_SVM_DISABLE )
     {
         printk("CPU%d: AMD SVM Extension is disabled in BIOS.\n", cpu);
         return -EINVAL;
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index 3e0c6c8476..ff583cf0ed 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -116,6 +116,9 @@
 #define  PASID_PASID_MASK                   0x000fffff
 #define  PASID_VALID                        (_AC(1, ULL) << 31)
 
+#define MSR_K8_VM_CR                        0xc0010114
+#define  VM_CR_SVM_DISABLE                  (_AC(1, ULL) <<  4)
+
 /*
  * Legacy MSR constants in need of cleanup.  No new MSRs below this comment.
  */
@@ -297,7 +300,6 @@
 #define MSR_K8_PSTATE6			0xc001006A
 #define MSR_K8_PSTATE7			0xc001006B
 #define MSR_K8_ENABLE_C1E		0xc0010055
-#define MSR_K8_VM_CR			0xc0010114
 #define MSR_K8_VM_HSAVE_PA		0xc0010117
 
 #define MSR_AMD_FAM15H_EVNTSEL0		0xc0010200
@@ -318,10 +320,6 @@
 #define MSR_K8_FEATURE_MASK		0xc0011004
 #define MSR_K8_EXT_FEATURE_MASK		0xc0011005
 
-/* MSR_K8_VM_CR bits: */
-#define _K8_VMCR_SVME_DISABLE		4
-#define K8_VMCR_SVME_DISABLE		(1 << _K8_VMCR_SVME_DISABLE)
-
 /* AMD64 MSRs */
 #define MSR_AMD64_NB_CFG		0xc001001f
 #define AMD64_NB_CFG_CF8_EXT_ENABLE_BIT	46
--
generated by git-patchbot for /home/xen/git/xen.git#staging


From xen-changelog-bounces@lists.xenproject.org Thu Dec 31 18:00:27 2020
Return-path: <xen-changelog-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xen.org
Delivery-date: Thu, 31 Dec 2020 18:00:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.60597.106348 (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2FP-0002ne-9C; Thu, 31 Dec 2020 18:00:27 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 60597.106348; Thu, 31 Dec 2020 18:00:27 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <xen-changelog-bounces@lists.xenproject.org>)
	id 1kv2FP-0002nW-6H; Thu, 31 Dec 2020 18:00:27 +0000
Received: by outflank-mailman (input) for mailman id 60597;
 Thu, 31 Dec 2020 18:00:25 +0000
Received: from mail.xenproject.org ([104.130.215.37])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FN-0002nP-Tm
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:25 +0000
Received: from xenbits.xenproject.org ([104.239.192.120])
 by mail.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FN-0003VQ-Su
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:25 +0000
Received: from xen by xenbits.xenproject.org with local (Exim 4.92)
 (envelope-from <ian.jackson@eu.citrix.com>) id 1kv2FN-000119-RQ
 for xen-changelog@lists.xenproject.org; Thu, 31 Dec 2020 18:00:25 +0000
X-BeenThere: xen-changelog@lists.xenproject.org
List-Id: "Change log for Mercurial \(receive only\)"
 <xen-changelog.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:xen-changelog@lists.xenproject.org>
List-Help: <mailto:xen-changelog-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/xen-changelog>, 
 <mailto:xen-changelog-request@lists.xenproject.org?subject=subscribe>
Errors-To: xen-changelog-bounces@lists.xenproject.org
Precedence: list
Sender: "Xen-changelog" <xen-changelog-bounces@lists.xenproject.org>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org;
	s=20200302mail; h=Date:Message-Id:Subject:Reply-To:To:From;
	bh=2rRupu3A/ggGMkC4lmAigWGlM6P1EsC7qv4qUtnLTW4=; b=Wt8C2e/3d4eR3WuFy7sYgtfwvm
	2qq7U7CJ1Qv4ZC2j92Red3RhIY/7G09eCB3hW8exws0BRCGp4sZhWl44qViITTO4WexOlKpOHGEcP
	b+UdJZWlhTap7T1bk5lp/LIBsMtZKADkEjd3bz+nZhYU8F+ejtxMcVw50Tq14kbE/cPQ=;
From: patchbot@xen.org
To: xen-changelog@lists.xenproject.org
Reply-To: xen-devel@lists.xenproject.org
Subject: [xen staging] xen: remove the usage of the P ar option
Message-Id: <E1kv2FN-000119-RQ@xenbits.xenproject.org>
Date: Thu, 31 Dec 2020 18:00:25 +0000

commit 1516ecd6f55fe3608f374f4f2548491472d1c9a1
Author:     Roger Pau Monne <roger.pau@citrix.com>
AuthorDate: Wed Dec 30 18:34:46 2020 +0100
Commit:     Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Thu Dec 31 16:19:00 2020 +0000

    xen: remove the usage of the P ar option
    
    It's not part of the POSIX standard [0] and as such non GNU ar
    implementations don't usually have it.
    
    It's not relevant for the use case here anyway, as the archive file is
    recreated every time due to the rm invocation before the ar call. No
    file name matching should happen so matching using the full path name
    or a relative one should yield the same result.
    
    This fixes the build on FreeBSD.
    
    While there also drop the s option, as ar will already generate a
    symbol table by default when creating the archive.
    
    [0] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ar.html
    
    Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
    Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/Rules.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index aba6ca2a90..ceb3d204b8 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -71,7 +71,7 @@ cmd_ld = $(LD) $(XEN_LDFLAGS) -r -o $@ $(filter-out %.a,$(real-prereqs)) \
 # ---------------------------------------------------------------------------
 
 quiet_cmd_ar = AR      $@
-cmd_ar = rm -f $@; $(AR) cPrs $@ $(real-prereqs)
+cmd_ar = rm -f $@; $(AR) cr $@ $(real-prereqs)
 
 # Objcopy
 # ---------------------------------------------------------------------------
--
generated by git-patchbot for /home/xen/git/xen.git#staging


